blob: 32aa5a69d07aca4cdb0723dc1205dacfa5e7ca31 [file] [log] [blame]
//===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Implements semantic analysis for C++ expressions.
///
//===----------------------------------------------------------------------===//
#include "clang/Sema/SemaInternal.h"
#include "TreeTransform.h"
#include "TypeLocBuilder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaLambda.h"
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
using namespace sema;
/// \brief Handle the result of the special case name lookup for inheriting
/// constructor declarations. 'NS::X::X' and 'NS::X<...>::X' are treated as
/// constructor names in member using declarations, even if 'X' is not the
/// name of the corresponding type.
ParsedType Sema::getInheritingConstructorName(CXXScopeSpec &SS,
SourceLocation NameLoc,
IdentifierInfo &Name) {
NestedNameSpecifier *NNS = SS.getScopeRep();
// Convert the nested-name-specifier into a type.
QualType Type;
switch (NNS->getKind()) {
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
Type = QualType(NNS->getAsType(), 0);
break;
case NestedNameSpecifier::Identifier:
// Strip off the last layer of the nested-name-specifier and build a
// typename type for it.
assert(NNS->getAsIdentifier() == &Name && "not a constructor name");
Type = Context.getDependentNameType(ETK_None, NNS->getPrefix(),
NNS->getAsIdentifier());
break;
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Super:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
llvm_unreachable("Nested name specifier is not a type for inheriting ctor");
}
// This reference to the type is located entirely at the location of the
// final identifier in the qualified-id.
return CreateParsedType(Type,
Context.getTrivialTypeSourceInfo(Type, NameLoc));
}
ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
IdentifierInfo &II,
SourceLocation NameLoc,
Scope *S, CXXScopeSpec &SS,
ParsedType ObjectTypePtr,
bool EnteringContext) {
// Determine where to perform name lookup.
// FIXME: This area of the standard is very messy, and the current
// wording is rather unclear about which scopes we search for the
// destructor name; see core issues 399 and 555. Issue 399 in
// particular shows where the current description of destructor name
// lookup is completely out of line with existing practice, e.g.,
// this appears to be ill-formed:
//
// namespace N {
// template <typename T> struct S {
// ~S();
// };
// }
//
// void f(N::S<int>* s) {
// s->N::S<int>::~S();
// }
//
// See also PR6358 and PR6359.
// For this reason, we're currently only doing the C++03 version of this
// code; the C++0x version has to wait until we get a proper spec.
QualType SearchType;
DeclContext *LookupCtx = nullptr;
bool isDependent = false;
bool LookInScope = false;
if (SS.isInvalid())
return nullptr;
// If we have an object type, it's because we are in a
// pseudo-destructor-expression or a member access expression, and
// we know what type we're looking for.
if (ObjectTypePtr)
SearchType = GetTypeFromParser(ObjectTypePtr);
if (SS.isSet()) {
NestedNameSpecifier *NNS = SS.getScopeRep();
bool AlreadySearched = false;
bool LookAtPrefix = true;
// C++11 [basic.lookup.qual]p6:
// If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier,
// the type-names are looked up as types in the scope designated by the
// nested-name-specifier. Similarly, in a qualified-id of the form:
//
// nested-name-specifier[opt] class-name :: ~ class-name
//
// the second class-name is looked up in the same scope as the first.
//
// Here, we determine whether the code below is permitted to look at the
// prefix of the nested-name-specifier.
DeclContext *DC = computeDeclContext(SS, EnteringContext);
if (DC && DC->isFileContext()) {
AlreadySearched = true;
LookupCtx = DC;
isDependent = false;
} else if (DC && isa<CXXRecordDecl>(DC)) {
LookAtPrefix = false;
LookInScope = true;
}
// The second case from the C++03 rules quoted further above.
NestedNameSpecifier *Prefix = nullptr;
if (AlreadySearched) {
// Nothing left to do.
} else if (LookAtPrefix && (Prefix = NNS->getPrefix())) {
CXXScopeSpec PrefixSS;
PrefixSS.Adopt(NestedNameSpecifierLoc(Prefix, SS.location_data()));
LookupCtx = computeDeclContext(PrefixSS, EnteringContext);
isDependent = isDependentScopeSpecifier(PrefixSS);
} else if (ObjectTypePtr) {
LookupCtx = computeDeclContext(SearchType);
isDependent = SearchType->isDependentType();
} else {
LookupCtx = computeDeclContext(SS, EnteringContext);
isDependent = LookupCtx && LookupCtx->isDependentContext();
}
} else if (ObjectTypePtr) {
// C++ [basic.lookup.classref]p3:
// If the unqualified-id is ~type-name, the type-name is looked up
// in the context of the entire postfix-expression. If the type T
// of the object expression is of a class type C, the type-name is
// also looked up in the scope of class C. At least one of the
// lookups shall find a name that refers to (possibly
// cv-qualified) T.
LookupCtx = computeDeclContext(SearchType);
isDependent = SearchType->isDependentType();
assert((isDependent || !SearchType->isIncompleteType()) &&
"Caller should have completed object type");
LookInScope = true;
} else {
// Perform lookup into the current scope (only).
LookInScope = true;
}
TypeDecl *NonMatchingTypeDecl = nullptr;
LookupResult Found(*this, &II, NameLoc, LookupOrdinaryName);
for (unsigned Step = 0; Step != 2; ++Step) {
// Look for the name first in the computed lookup context (if we
// have one) and, if that fails to find a match, in the scope (if
// we're allowed to look there).
Found.clear();
if (Step == 0 && LookupCtx)
LookupQualifiedName(Found, LookupCtx);
else if (Step == 1 && LookInScope && S)
LookupName(Found, S);
else
continue;
// FIXME: Should we be suppressing ambiguities here?
if (Found.isAmbiguous())
return nullptr;
if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
QualType T = Context.getTypeDeclType(Type);
MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);
if (SearchType.isNull() || SearchType->isDependentType() ||
Context.hasSameUnqualifiedType(T, SearchType)) {
// We found our type!
return CreateParsedType(T,
Context.getTrivialTypeSourceInfo(T, NameLoc));
}
if (!SearchType.isNull())
NonMatchingTypeDecl = Type;
}
// If the name that we found is a class template name, and it is
// the same name as the template name in the last part of the
// nested-name-specifier (if present) or the object type, then
// this is the destructor for that class.
// FIXME: This is a workaround until we get real drafting for core
// issue 399, for which there isn't even an obvious direction.
if (ClassTemplateDecl *Template = Found.getAsSingle<ClassTemplateDecl>()) {
QualType MemberOfType;
if (SS.isSet()) {
if (DeclContext *Ctx = computeDeclContext(SS, EnteringContext)) {
// Figure out the type of the context, if it has one.
if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx))
MemberOfType = Context.getTypeDeclType(Record);
}
}
if (MemberOfType.isNull())
MemberOfType = SearchType;
if (MemberOfType.isNull())
continue;
// We're referring into a class template specialization. If the
// class template we found is the same as the template being
// specialized, we found what we are looking for.
if (const RecordType *Record = MemberOfType->getAs<RecordType>()) {
if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
if (Spec->getSpecializedTemplate()->getCanonicalDecl() ==
Template->getCanonicalDecl())
return CreateParsedType(
MemberOfType,
Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc));
}
continue;
}
// We're referring to an unresolved class template
// specialization. Determine whether we class template we found
// is the same as the template being specialized or, if we don't
// know which template is being specialized, that it at least
// has the same name.
if (const TemplateSpecializationType *SpecType
= MemberOfType->getAs<TemplateSpecializationType>()) {
TemplateName SpecName = SpecType->getTemplateName();
// The class template we found is the same template being
// specialized.
if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) {
if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl())
return CreateParsedType(
MemberOfType,
Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc));
continue;
}
// The class template we found has the same name as the
// (dependent) template name being specialized.
if (DependentTemplateName *DepTemplate
= SpecName.getAsDependentTemplateName()) {
if (DepTemplate->isIdentifier() &&
DepTemplate->getIdentifier() == Template->getIdentifier())
return CreateParsedType(
MemberOfType,
Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc));
continue;
}
}
}
}
if (isDependent) {
// We didn't find our type, but that's okay: it's dependent
// anyway.
// FIXME: What if we have no nested-name-specifier?
QualType T = CheckTypenameType(ETK_None, SourceLocation(),
SS.getWithLocInContext(Context),
II, NameLoc);
return ParsedType::make(T);
}
if (NonMatchingTypeDecl) {
QualType T = Context.getTypeDeclType(NonMatchingTypeDecl);
Diag(NameLoc, diag::err_destructor_expr_type_mismatch)
<< T << SearchType;
Diag(NonMatchingTypeDecl->getLocation(), diag::note_destructor_type_here)
<< T;
} else if (ObjectTypePtr)
Diag(NameLoc, diag::err_ident_in_dtor_not_a_type)
<< &II;
else {
SemaDiagnosticBuilder DtorDiag = Diag(NameLoc,
diag::err_destructor_class_name);
if (S) {
const DeclContext *Ctx = S->getEntity();
if (const CXXRecordDecl *Class = dyn_cast_or_null<CXXRecordDecl>(Ctx))
DtorDiag << FixItHint::CreateReplacement(SourceRange(NameLoc),
Class->getNameAsString());
}
}
return nullptr;
}
ParsedType Sema::getDestructorType(const DeclSpec& DS, ParsedType ObjectType) {
if (DS.getTypeSpecType() == DeclSpec::TST_error || !ObjectType)
return nullptr;
assert(DS.getTypeSpecType() == DeclSpec::TST_decltype
&& "only get destructor types from declspecs");
QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc());
QualType SearchType = GetTypeFromParser(ObjectType);
if (SearchType->isDependentType() || Context.hasSameUnqualifiedType(SearchType, T)) {
return ParsedType::make(T);
}
Diag(DS.getTypeSpecTypeLoc(), diag::err_destructor_expr_type_mismatch)
<< T << SearchType;
return nullptr;
}
bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
const UnqualifiedId &Name) {
assert(Name.getKind() == UnqualifiedId::IK_LiteralOperatorId);
if (!SS.isValid())
return false;
switch (SS.getScopeRep()->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
// Per C++11 [over.literal]p2, literal operators can only be declared at
// namespace scope. Therefore, this unqualified-id cannot name anything.
// Reject it early, because we have no AST representation for this in the
// case where the scope is dependent.
Diag(Name.getLocStart(), diag::err_literal_operator_id_outside_namespace)
<< SS.getScopeRep();
return true;
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Super:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
return false;
}
llvm_unreachable("unknown nested name specifier kind");
}
/// \brief Build a C++ typeid expression with a type operand.
ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
SourceLocation TypeidLoc,
TypeSourceInfo *Operand,
SourceLocation RParenLoc) {
// C++ [expr.typeid]p4:
// The top-level cv-qualifiers of the lvalue expression or the type-id
// that is the operand of typeid are always ignored.
// If the type of the type-id is a class type or a reference to a class
// type, the class shall be completely-defined.
Qualifiers Quals;
QualType T
= Context.getUnqualifiedArrayType(Operand->getType().getNonReferenceType(),
Quals);
if (T->getAs<RecordType>() &&
RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
return ExprError();
if (T->isVariablyModifiedType())
return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << T);
return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand,
SourceRange(TypeidLoc, RParenLoc));
}
/// \brief Build a C++ typeid expression with an expression operand.
ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
SourceLocation TypeidLoc,
Expr *E,
SourceLocation RParenLoc) {
bool WasEvaluated = false;
if (E && !E->isTypeDependent()) {
if (E->getType()->isPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(E);
if (result.isInvalid()) return ExprError();
E = result.get();
}
QualType T = E->getType();
if (const RecordType *RecordT = T->getAs<RecordType>()) {
CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl());
// C++ [expr.typeid]p3:
// [...] If the type of the expression is a class type, the class
// shall be completely-defined.
if (RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
return ExprError();
// C++ [expr.typeid]p3:
// When typeid is applied to an expression other than an glvalue of a
// polymorphic class type [...] [the] expression is an unevaluated
// operand. [...]
if (RecordD->isPolymorphic() && E->isGLValue()) {
// The subexpression is potentially evaluated; switch the context
// and recheck the subexpression.
ExprResult Result = TransformToPotentiallyEvaluated(E);
if (Result.isInvalid()) return ExprError();
E = Result.get();
// We require a vtable to query the type at run time.
MarkVTableUsed(TypeidLoc, RecordD);
WasEvaluated = true;
}
}
// C++ [expr.typeid]p4:
// [...] If the type of the type-id is a reference to a possibly
// cv-qualified type, the result of the typeid expression refers to a
// std::type_info object representing the cv-unqualified referenced
// type.
Qualifiers Quals;
QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
if (!Context.hasSameType(T, UnqualT)) {
T = UnqualT;
E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).get();
}
}
if (E->getType()->isVariablyModifiedType())
return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid)
<< E->getType());
else if (ActiveTemplateInstantiations.empty() &&
E->HasSideEffects(Context, WasEvaluated)) {
// The expression operand for typeid is in an unevaluated expression
// context, so side effects could result in unintended consequences.
Diag(E->getExprLoc(), WasEvaluated
? diag::warn_side_effects_typeid
: diag::warn_side_effects_unevaluated_context);
}
return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E,
SourceRange(TypeidLoc, RParenLoc));
}
/// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
ExprResult
Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
// Find the std::type_info type.
if (!getStdNamespace())
return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
if (!CXXTypeInfoDecl) {
IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
LookupQualifiedName(R, getStdNamespace());
CXXTypeInfoDecl = R.getAsSingle<RecordDecl>();
// Microsoft's typeinfo doesn't have type_info in std but in the global
// namespace if _HAS_EXCEPTIONS is defined to 0. See PR13153.
if (!CXXTypeInfoDecl && LangOpts.MSVCCompat) {
LookupQualifiedName(R, Context.getTranslationUnitDecl());
CXXTypeInfoDecl = R.getAsSingle<RecordDecl>();
}
if (!CXXTypeInfoDecl)
return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
}
if (!getLangOpts().RTTI) {
return ExprError(Diag(OpLoc, diag::err_no_typeid_with_fno_rtti));
}
QualType TypeInfoType = Context.getTypeDeclType(CXXTypeInfoDecl);
if (isType) {
// The operand is a type; handle it as such.
TypeSourceInfo *TInfo = nullptr;
QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
&TInfo);
if (T.isNull())
return ExprError();
if (!TInfo)
TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
return BuildCXXTypeId(TypeInfoType, OpLoc, TInfo, RParenLoc);
}
// The operand is an expression.
return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
}
/// \brief Build a Microsoft __uuidof expression with a type operand.
ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
SourceLocation TypeidLoc,
TypeSourceInfo *Operand,
SourceLocation RParenLoc) {
if (!Operand->getType()->isDependentType()) {
bool HasMultipleGUIDs = false;
if (!CXXUuidofExpr::GetUuidAttrOfType(Operand->getType(),
&HasMultipleGUIDs)) {
if (HasMultipleGUIDs)
return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
else
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
}
}
return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand,
SourceRange(TypeidLoc, RParenLoc));
}
/// \brief Build a Microsoft __uuidof expression with an expression operand.
ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
SourceLocation TypeidLoc,
Expr *E,
SourceLocation RParenLoc) {
if (!E->getType()->isDependentType()) {
bool HasMultipleGUIDs = false;
if (!CXXUuidofExpr::GetUuidAttrOfType(E->getType(), &HasMultipleGUIDs) &&
!E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
if (HasMultipleGUIDs)
return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
else
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
}
}
return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E,
SourceRange(TypeidLoc, RParenLoc));
}
/// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression);
ExprResult
Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc,
bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
// If MSVCGuidDecl has not been cached, do the lookup.
if (!MSVCGuidDecl) {
IdentifierInfo *GuidII = &PP.getIdentifierTable().get("_GUID");
LookupResult R(*this, GuidII, SourceLocation(), LookupTagName);
LookupQualifiedName(R, Context.getTranslationUnitDecl());
MSVCGuidDecl = R.getAsSingle<RecordDecl>();
if (!MSVCGuidDecl)
return ExprError(Diag(OpLoc, diag::err_need_header_before_ms_uuidof));
}
QualType GuidType = Context.getTypeDeclType(MSVCGuidDecl);
if (isType) {
// The operand is a type; handle it as such.
TypeSourceInfo *TInfo = nullptr;
QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
&TInfo);
if (T.isNull())
return ExprError();
if (!TInfo)
TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
return BuildCXXUuidof(GuidType, OpLoc, TInfo, RParenLoc);
}
// The operand is an expression.
return BuildCXXUuidof(GuidType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
}
/// ActOnCXXBoolLiteral - Parse {true,false} literals.
ExprResult
Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
"Unknown C++ Boolean value!");
return new (Context)
CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
}
/// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
ExprResult
Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
return new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc);
}
/// ActOnCXXThrow - Parse throw expressions.
ExprResult
Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) {
bool IsThrownVarInScope = false;
if (Ex) {
// C++0x [class.copymove]p31:
// When certain criteria are met, an implementation is allowed to omit the
// copy/move construction of a class object [...]
//
// - in a throw-expression, when the operand is the name of a
// non-volatile automatic object (other than a function or catch-
// clause parameter) whose scope does not extend beyond the end of the
// innermost enclosing try-block (if there is one), the copy/move
// operation from the operand to the exception object (15.1) can be
// omitted by constructing the automatic object directly into the
// exception object
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex->IgnoreParens()))
if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
if (Var->hasLocalStorage() && !Var->getType().isVolatileQualified()) {
for( ; S; S = S->getParent()) {
if (S->isDeclScope(Var)) {
IsThrownVarInScope = true;
break;
}
if (S->getFlags() &
(Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
Scope::FunctionPrototypeScope | Scope::ObjCMethodScope |
Scope::TryScope))
break;
}
}
}
}
return BuildCXXThrow(OpLoc, Ex, IsThrownVarInScope);
}
ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
bool IsThrownVarInScope) {
// Don't report an error if 'throw' is used in system headers.
if (!getLangOpts().CXXExceptions &&
!getSourceManager().isInSystemHeader(OpLoc))
Diag(OpLoc, diag::err_exceptions_disabled) << "throw";
if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw";
if (Ex && !Ex->isTypeDependent()) {
QualType ExceptionObjectTy = Context.getExceptionObjectType(Ex->getType());
if (CheckCXXThrowOperand(OpLoc, ExceptionObjectTy, Ex))
return ExprError();
// Initialize the exception result. This implicitly weeds out
// abstract types or types with inaccessible copy constructors.
// C++0x [class.copymove]p31:
// When certain criteria are met, an implementation is allowed to omit the
// copy/move construction of a class object [...]
//
// - in a throw-expression, when the operand is the name of a
// non-volatile automatic object (other than a function or
// catch-clause
// parameter) whose scope does not extend beyond the end of the
// innermost enclosing try-block (if there is one), the copy/move
// operation from the operand to the exception object (15.1) can be
// omitted by constructing the automatic object directly into the
// exception object
const VarDecl *NRVOVariable = nullptr;
if (IsThrownVarInScope)
NRVOVariable = getCopyElisionCandidate(QualType(), Ex, false);
InitializedEntity Entity = InitializedEntity::InitializeException(
OpLoc, ExceptionObjectTy,
/*NRVO=*/NRVOVariable != nullptr);
ExprResult Res = PerformMoveOrCopyInitialization(
Entity, NRVOVariable, QualType(), Ex, IsThrownVarInScope);
if (Res.isInvalid())
return ExprError();
Ex = Res.get();
}
return new (Context)
CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope);
}
static void
collectPublicBases(CXXRecordDecl *RD,
llvm::DenseMap<CXXRecordDecl *, unsigned> &SubobjectsSeen,
llvm::SmallPtrSetImpl<CXXRecordDecl *> &VBases,
llvm::SetVector<CXXRecordDecl *> &PublicSubobjectsSeen,
bool ParentIsPublic) {
for (const CXXBaseSpecifier &BS : RD->bases()) {
CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl();
bool NewSubobject;
// Virtual bases constitute the same subobject. Non-virtual bases are
// always distinct subobjects.
if (BS.isVirtual())
NewSubobject = VBases.insert(BaseDecl).second;
else
NewSubobject = true;
if (NewSubobject)
++SubobjectsSeen[BaseDecl];
// Only add subobjects which have public access throughout the entire chain.
bool PublicPath = ParentIsPublic && BS.getAccessSpecifier() == AS_public;
if (PublicPath)
PublicSubobjectsSeen.insert(BaseDecl);
// Recurse on to each base subobject.
collectPublicBases(BaseDecl, SubobjectsSeen, VBases, PublicSubobjectsSeen,
PublicPath);
}
}
static void getUnambiguousPublicSubobjects(
CXXRecordDecl *RD, llvm::SmallVectorImpl<CXXRecordDecl *> &Objects) {
llvm::DenseMap<CXXRecordDecl *, unsigned> SubobjectsSeen;
llvm::SmallSet<CXXRecordDecl *, 2> VBases;
llvm::SetVector<CXXRecordDecl *> PublicSubobjectsSeen;
SubobjectsSeen[RD] = 1;
PublicSubobjectsSeen.insert(RD);
collectPublicBases(RD, SubobjectsSeen, VBases, PublicSubobjectsSeen,
/*ParentIsPublic=*/true);
for (CXXRecordDecl *PublicSubobject : PublicSubobjectsSeen) {
// Skip ambiguous objects.
if (SubobjectsSeen[PublicSubobject] > 1)
continue;
Objects.push_back(PublicSubobject);
}
}
/// CheckCXXThrowOperand - Validate the operand of a throw.
bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc,
QualType ExceptionObjectTy, Expr *E) {
// If the type of the exception would be an incomplete type or a pointer
// to an incomplete type other than (cv) void the program is ill-formed.
QualType Ty = ExceptionObjectTy;
bool isPointer = false;
if (const PointerType* Ptr = Ty->getAs<PointerType>()) {
Ty = Ptr->getPointeeType();
isPointer = true;
}
if (!isPointer || !Ty->isVoidType()) {
if (RequireCompleteType(ThrowLoc, Ty,
isPointer ? diag::err_throw_incomplete_ptr
: diag::err_throw_incomplete,
E->getSourceRange()))
return true;
if (RequireNonAbstractType(ThrowLoc, ExceptionObjectTy,
diag::err_throw_abstract_type, E))
return true;
}
// If the exception has class type, we need additional handling.
CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
if (!RD)
return false;
// If we are throwing a polymorphic class type or pointer thereof,
// exception handling will make use of the vtable.
MarkVTableUsed(ThrowLoc, RD);
// If a pointer is thrown, the referenced object will not be destroyed.
if (isPointer)
return false;
// If the class has a destructor, we must be able to call it.
if (!RD->hasIrrelevantDestructor()) {
if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) {
MarkFunctionReferenced(E->getExprLoc(), Destructor);
CheckDestructorAccess(E->getExprLoc(), Destructor,
PDiag(diag::err_access_dtor_exception) << Ty);
if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
return true;
}
}
// The MSVC ABI creates a list of all types which can catch the exception
// object. This list also references the appropriate copy constructor to call
// if the object is caught by value and has a non-trivial copy constructor.
if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
// We are only interested in the public, unambiguous bases contained within
// the exception object. Bases which are ambiguous or otherwise
// inaccessible are not catchable types.
llvm::SmallVector<CXXRecordDecl *, 2> UnambiguousPublicSubobjects;
getUnambiguousPublicSubobjects(RD, UnambiguousPublicSubobjects);
for (CXXRecordDecl *Subobject : UnambiguousPublicSubobjects) {
// Attempt to lookup the copy constructor. Various pieces of machinery
// will spring into action, like template instantiation, which means this
// cannot be a simple walk of the class's decls. Instead, we must perform
// lookup and overload resolution.
CXXConstructorDecl *CD = LookupCopyingConstructor(Subobject, 0);
if (!CD)
continue;
// Mark the constructor referenced as it is used by this throw expression.
MarkFunctionReferenced(E->getExprLoc(), CD);
// Skip this copy constructor if it is trivial, we don't need to record it
// in the catchable type data.
if (CD->isTrivial())
continue;
// The copy constructor is non-trivial, create a mapping from this class
// type to this constructor.
// N.B. The selection of copy constructor is not sensitive to this
// particular throw-site. Lookup will be performed at the catch-site to
// ensure that the copy constructor is, in fact, accessible (via
// friendship or any other means).
Context.addCopyConstructorForExceptionObject(Subobject, CD);
// We don't keep the instantiated default argument expressions around so
// we must rebuild them here.
for (unsigned I = 1, E = CD->getNumParams(); I != E; ++I) {
// Skip any default arguments that we've already instantiated.
if (Context.getDefaultArgExprForConstructor(CD, I))
continue;
Expr *DefaultArg =
BuildCXXDefaultArgExpr(ThrowLoc, CD, CD->getParamDecl(I)).get();
Context.addDefaultArgExprForConstructor(CD, I, DefaultArg);
}
}
}
return false;
}
QualType Sema::getCurrentThisType() {
DeclContext *DC = getFunctionLevelDeclContext();
QualType ThisTy = CXXThisTypeOverride;
if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC)) {
if (method && method->isInstance())
ThisTy = method->getThisType(Context);
}
if (ThisTy.isNull()) {
if (isGenericLambdaCallOperatorSpecialization(CurContext) &&
CurContext->getParent()->getParent()->isRecord()) {
// This is a generic lambda call operator that is being instantiated
// within a default initializer - so use the enclosing class as 'this'.
// There is no enclosing member function to retrieve the 'this' pointer
// from.
QualType ClassTy = Context.getTypeDeclType(
cast<CXXRecordDecl>(CurContext->getParent()->getParent()));
// There are no cv-qualifiers for 'this' within default initializers,
// per [expr.prim.general]p4.
return Context.getPointerType(ClassTy);
}
}
return ThisTy;
}
Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S,
Decl *ContextDecl,
unsigned CXXThisTypeQuals,
bool Enabled)
: S(S), OldCXXThisTypeOverride(S.CXXThisTypeOverride), Enabled(false)
{
if (!Enabled || !ContextDecl)
return;
CXXRecordDecl *Record = nullptr;
if (ClassTemplateDecl *Template = dyn_cast<ClassTemplateDecl>(ContextDecl))
Record = Template->getTemplatedDecl();
else
Record = cast<CXXRecordDecl>(ContextDecl);
S.CXXThisTypeOverride
= S.Context.getPointerType(
S.Context.getRecordType(Record).withCVRQualifiers(CXXThisTypeQuals));
this->Enabled = true;
}
Sema::CXXThisScopeRAII::~CXXThisScopeRAII() {
if (Enabled) {
S.CXXThisTypeOverride = OldCXXThisTypeOverride;
}
}
static Expr *captureThis(ASTContext &Context, RecordDecl *RD,
QualType ThisTy, SourceLocation Loc) {
FieldDecl *Field
= FieldDecl::Create(Context, RD, Loc, Loc, nullptr, ThisTy,
Context.getTrivialTypeSourceInfo(ThisTy, Loc),
nullptr, false, ICIS_NoInit);
Field->setImplicit(true);
Field->setAccess(AS_private);
RD->addDecl(Field);
return new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit*/true);
}
bool Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit,
bool BuildAndDiagnose, const unsigned *const FunctionScopeIndexToStopAt) {
// We don't need to capture this in an unevaluated context.
if (isUnevaluatedContext() && !Explicit)
return true;
const unsigned MaxFunctionScopesIndex = FunctionScopeIndexToStopAt ?
*FunctionScopeIndexToStopAt : FunctionScopes.size() - 1;
// Otherwise, check that we can capture 'this'.
unsigned NumClosures = 0;
for (unsigned idx = MaxFunctionScopesIndex; idx != 0; idx--) {
if (CapturingScopeInfo *CSI =
dyn_cast<CapturingScopeInfo>(FunctionScopes[idx])) {
if (CSI->CXXThisCaptureIndex != 0) {
// 'this' is already being captured; there isn't anything more to do.
break;
}
LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI);
if (LSI && isGenericLambdaCallOperatorSpecialization(LSI->CallOperator)) {
// This context can't implicitly capture 'this'; fail out.
if (BuildAndDiagnose)
Diag(Loc, diag::err_this_capture) << Explicit;
return true;
}
if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref ||
CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval ||
CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block ||
CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_CapturedRegion ||
Explicit) {
// This closure can capture 'this'; continue looking upwards.
NumClosures++;
Explicit = false;
continue;
}
// This context can't implicitly capture 'this'; fail out.
if (BuildAndDiagnose)
Diag(Loc, diag::err_this_capture) << Explicit;
return true;
}
break;
}
if (!BuildAndDiagnose) return false;
// Mark that we're implicitly capturing 'this' in all the scopes we skipped.
// FIXME: We need to delay this marking in PotentiallyPotentiallyEvaluated
// contexts.
for (unsigned idx = MaxFunctionScopesIndex; NumClosures;
--idx, --NumClosures) {
CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
Expr *ThisExpr = nullptr;
QualType ThisTy = getCurrentThisType();
if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI))
// For lambda expressions, build a field and an initializing expression.
ThisExpr = captureThis(Context, LSI->Lambda, ThisTy, Loc);
else if (CapturedRegionScopeInfo *RSI
= dyn_cast<CapturedRegionScopeInfo>(FunctionScopes[idx]))
ThisExpr = captureThis(Context, RSI->TheRecordDecl, ThisTy, Loc);
bool isNested = NumClosures > 1;
CSI->addThisCapture(isNested, Loc, ThisTy, ThisExpr);
}
return false;
}
ExprResult Sema::ActOnCXXThis(SourceLocation Loc) {
/// C++ 9.3.2: In the body of a non-static member function, the keyword this
/// is a non-lvalue expression whose value is the address of the object for
/// which the function is called.
QualType ThisTy = getCurrentThisType();
if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use);
CheckCXXThisCapture(Loc);
return new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false);
}
bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) {
// If we're outside the body of a member function, then we'll have a specified
// type for 'this'.
if (CXXThisTypeOverride.isNull())
return false;
// Determine whether we're looking into a class that's currently being
// defined.
CXXRecordDecl *Class = BaseType->getAsCXXRecordDecl();
return Class && Class->isBeingDefined();
}
ExprResult
Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
SourceLocation LParenLoc,
MultiExprArg exprs,
SourceLocation RParenLoc) {
if (!TypeRep)
return ExprError();
TypeSourceInfo *TInfo;
QualType Ty = GetTypeFromParser(TypeRep, &TInfo);
if (!TInfo)
TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation());
return BuildCXXTypeConstructExpr(TInfo, LParenLoc, exprs, RParenLoc);
}
/// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
/// Can be interpreted either as function-style casting ("int(x)")
/// or class type construction ("ClassType(x,y,z)")
/// or creation of a value-initialized type ("int()").
ExprResult
Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
SourceLocation LParenLoc,
MultiExprArg Exprs,
SourceLocation RParenLoc) {
QualType Ty = TInfo->getType();
SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
return CXXUnresolvedConstructExpr::Create(Context, TInfo, LParenLoc, Exprs,
RParenLoc);
}
bool ListInitialization = LParenLoc.isInvalid();
assert((!ListInitialization || (Exprs.size() == 1 && isa<InitListExpr>(Exprs[0])))
&& "List initialization must have initializer list as expression.");
SourceRange FullRange = SourceRange(TyBeginLoc,
ListInitialization ? Exprs[0]->getSourceRange().getEnd() : RParenLoc);
// C++ [expr.type.conv]p1:
// If the expression list is a single expression, the type conversion
// expression is equivalent (in definedness, and if defined in meaning) to the
// corresponding cast expression.
if (Exprs.size() == 1 && !ListInitialization) {
Expr *Arg = Exprs[0];
return BuildCXXFunctionalCastExpr(TInfo, LParenLoc, Arg, RParenLoc);
}
// C++14 [expr.type.conv]p2: The expression T(), where T is a
// simple-type-specifier or typename-specifier for a non-array complete
// object type or the (possibly cv-qualified) void type, creates a prvalue
// of the specified type, whose value is that produced by value-initializing
// an object of type T.
QualType ElemTy = Ty;
if (Ty->isArrayType()) {
if (!ListInitialization)
return ExprError(Diag(TyBeginLoc,
diag::err_value_init_for_array_type) << FullRange);
ElemTy = Context.getBaseElementType(Ty);
}
if (!ListInitialization && Ty->isFunctionType())
return ExprError(Diag(TyBeginLoc, diag::err_value_init_for_function_type)
<< FullRange);
if (!Ty->isVoidType() &&
RequireCompleteType(TyBeginLoc, ElemTy,
diag::err_invalid_incomplete_type_use, FullRange))
return ExprError();
if (RequireNonAbstractType(TyBeginLoc, Ty,
diag::err_allocation_of_abstract_type))
return ExprError();
InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo);
InitializationKind Kind =
Exprs.size() ? ListInitialization
? InitializationKind::CreateDirectList(TyBeginLoc)
: InitializationKind::CreateDirect(TyBeginLoc, LParenLoc, RParenLoc)
: InitializationKind::CreateValue(TyBeginLoc, LParenLoc, RParenLoc);
InitializationSequence InitSeq(*this, Entity, Kind, Exprs);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Exprs);
if (Result.isInvalid() || !ListInitialization)
return Result;
Expr *Inner = Result.get();
if (CXXBindTemporaryExpr *BTE = dyn_cast_or_null<CXXBindTemporaryExpr>(Inner))
Inner = BTE->getSubExpr();
if (!isa<CXXTemporaryObjectExpr>(Inner)) {
// If we created a CXXTemporaryObjectExpr, that node also represents the
// functional cast. Otherwise, create an explicit cast to represent
// the syntactic form of a functional-style cast that was used here.
//
// FIXME: Creating a CXXFunctionalCastExpr around a CXXConstructExpr
// would give a more consistent AST representation than using a
// CXXTemporaryObjectExpr. It's also weird that the functional cast
// is sometimes handled by initialization and sometimes not.
QualType ResultType = Result.get()->getType();
Result = CXXFunctionalCastExpr::Create(
Context, ResultType, Expr::getValueKindForType(TInfo->getType()), TInfo,
CK_NoOp, Result.get(), /*Path=*/nullptr, LParenLoc, RParenLoc);
}
return Result;
}
/// doesUsualArrayDeleteWantSize - Answers whether the usual
/// operator delete[] for the given type has a size_t parameter.
static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc,
QualType allocType) {
const RecordType *record =
allocType->getBaseElementTypeUnsafe()->getAs<RecordType>();
if (!record) return false;
// Try to find an operator delete[] in class scope.
DeclarationName deleteName =
S.Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
LookupResult ops(S, deleteName, loc, Sema::LookupOrdinaryName);
S.LookupQualifiedName(ops, record->getDecl());
// We're just doing this for information.
ops.suppressDiagnostics();
// Very likely: there's no operator delete[].
if (ops.empty()) return false;
// If it's ambiguous, it should be illegal to call operator delete[]
// on this thing, so it doesn't matter if we allocate extra space or not.
if (ops.isAmbiguous()) return false;
LookupResult::Filter filter = ops.makeFilter();
while (filter.hasNext()) {
NamedDecl *del = filter.next()->getUnderlyingDecl();
// C++0x [basic.stc.dynamic.deallocation]p2:
// A template instance is never a usual deallocation function,
// regardless of its signature.
if (isa<FunctionTemplateDecl>(del)) {
filter.erase();
continue;
}
// C++0x [basic.stc.dynamic.deallocation]p2:
// If class T does not declare [an operator delete[] with one
// parameter] but does declare a member deallocation function
// named operator delete[] with exactly two parameters, the
// second of which has type std::size_t, then this function
// is a usual deallocation function.
if (!cast<CXXMethodDecl>(del)->isUsualDeallocationFunction()) {
filter.erase();
continue;
}
}
filter.done();
if (!ops.isSingleResult()) return false;
const FunctionDecl *del = cast<FunctionDecl>(ops.getFoundDecl());
return (del->getNumParams() == 2);
}
/// \brief Parsed a C++ 'new' expression (C++ 5.3.4).
///
/// E.g.:
/// @code new (memory) int[size][4] @endcode
/// or
/// @code ::new Foo(23, "hello") @endcode
///
/// \param StartLoc The first location of the expression.
/// \param UseGlobal True if 'new' was prefixed with '::'.
/// \param PlacementLParen Opening paren of the placement arguments.
/// \param PlacementArgs Placement new arguments.
/// \param PlacementRParen Closing paren of the placement arguments.
/// \param TypeIdParens If the type is in parens, the source range.
/// \param D The type to be allocated, as well as array dimensions.
/// \param Initializer The initializing expression or initializer-list, or null
/// if there is none.
ExprResult
Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
SourceLocation PlacementRParen, SourceRange TypeIdParens,
Declarator &D, Expr *Initializer) {
bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType();
Expr *ArraySize = nullptr;
// If the specified type is an array, unwrap it and save the expression.
if (D.getNumTypeObjects() > 0 &&
D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
DeclaratorChunk &Chunk = D.getTypeObject(0);
if (TypeContainsAuto)
return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto)
<< D.getSourceRange());
if (Chunk.Arr.hasStatic)
return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new)
<< D.getSourceRange());
if (!Chunk.Arr.NumElts)
return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size)
<< D.getSourceRange());
ArraySize = static_cast<Expr*>(Chunk.Arr.NumElts);
D.DropFirstTypeObject();
}
// Every dimension shall be of constant size.
if (ArraySize) {
for (unsigned I = 0, N = D.getNumTypeObjects(); I < N; ++I) {
if (D.getTypeObject(I).Kind != DeclaratorChunk::Array)
break;
DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr;
if (Expr *NumElts = (Expr *)Array.NumElts) {
if (!NumElts->isTypeDependent() && !NumElts->isValueDependent()) {
if (getLangOpts().CPlusPlus14) {
// C++1y [expr.new]p6: Every constant-expression in a noptr-new-declarator
// shall be a converted constant expression (5.19) of type std::size_t
// and shall evaluate to a strictly positive value.
unsigned IntWidth = Context.getTargetInfo().getIntWidth();
assert(IntWidth && "Builtin type of size 0?");
llvm::APSInt Value(IntWidth);
Array.NumElts
= CheckConvertedConstantExpression(NumElts, Context.getSizeType(), Value,
CCEK_NewExpr)
.get();
} else {
Array.NumElts
= VerifyIntegerConstantExpression(NumElts, nullptr,
diag::err_new_array_nonconst)
.get();
}
if (!Array.NumElts)
return ExprError();
}
}
}
}
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/nullptr);
QualType AllocType = TInfo->getType();
if (D.isInvalidType())
return ExprError();
SourceRange DirectInitRange;
if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer))
DirectInitRange = List->getSourceRange();
return BuildCXXNew(SourceRange(StartLoc, D.getLocEnd()), UseGlobal,
PlacementLParen,
PlacementArgs,
PlacementRParen,
TypeIdParens,
AllocType,
TInfo,
ArraySize,
DirectInitRange,
Initializer,
TypeContainsAuto);
}
static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,
Expr *Init) {
if (!Init)
return true;
if (ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init))
return PLE->getNumExprs() == 0;
if (isa<ImplicitValueInitExpr>(Init))
return true;
else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init))
return !CCE->isListInitialization() &&
CCE->getConstructor()->isDefaultConstructor();
else if (Style == CXXNewExpr::ListInit) {
assert(isa<InitListExpr>(Init) &&
"Shouldn't create list CXXConstructExprs for arrays.");
return true;
}
return false;
}
ExprResult
Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
SourceLocation PlacementLParen,
MultiExprArg PlacementArgs,
SourceLocation PlacementRParen,
SourceRange TypeIdParens,
QualType AllocType,
TypeSourceInfo *AllocTypeInfo,
Expr *ArraySize,
SourceRange DirectInitRange,
Expr *Initializer,
bool TypeMayContainAuto) {
SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
SourceLocation StartLoc = Range.getBegin();
CXXNewExpr::InitializationStyle initStyle;
if (DirectInitRange.isValid()) {
assert(Initializer && "Have parens but no initializer.");
initStyle = CXXNewExpr::CallInit;
} else if (Initializer && isa<InitListExpr>(Initializer))
initStyle = CXXNewExpr::ListInit;
else {
assert((!Initializer || isa<ImplicitValueInitExpr>(Initializer) ||
isa<CXXConstructExpr>(Initializer)) &&
"Initializer expression that cannot have been implicitly created.");
initStyle = CXXNewExpr::NoInit;
}
Expr **Inits = &Initializer;
unsigned NumInits = Initializer ? 1 : 0;
if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer)) {
assert(initStyle == CXXNewExpr::CallInit && "paren init for non-call init");
Inits = List->getExprs();
NumInits = List->getNumExprs();
}
// C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
if (TypeMayContainAuto && AllocType->isUndeducedType()) {
if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
<< AllocType << TypeRange);
if (initStyle == CXXNewExpr::ListInit ||
(NumInits == 1 && isa<InitListExpr>(Inits[0])))
return ExprError(Diag(Inits[0]->getLocStart(),
diag::err_auto_new_list_init)
<< AllocType << TypeRange);
if (NumInits > 1) {
Expr *FirstBad = Inits[1];
return ExprError(Diag(FirstBad->getLocStart(),
diag::err_auto_new_ctor_multiple_expressions)
<< AllocType << TypeRange);
}
Expr *Deduce = Inits[0];
QualType DeducedType;
if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed)
return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
<< AllocType << Deduce->getType()
<< TypeRange << Deduce->getSourceRange());
if (DeducedType.isNull())
return ExprError();
AllocType = DeducedType;
}
// Per C++0x [expr.new]p5, the type being constructed may be a
// typedef of an array type.
if (!ArraySize) {
if (const ConstantArrayType *Array
= Context.getAsConstantArrayType(AllocType)) {
ArraySize = IntegerLiteral::Create(Context, Array->getSize(),
Context.getSizeType(),
TypeRange.getEnd());
AllocType = Array->getElementType();
}
}
if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange))
return ExprError();
if (initStyle == CXXNewExpr::ListInit &&
isStdInitializerList(AllocType, nullptr)) {
Diag(AllocTypeInfo->getTypeLoc().getBeginLoc(),
diag::warn_dangling_std_initializer_list)
<< /*at end of FE*/0 << Inits[0]->getSourceRange();
}
// In ARC, infer 'retaining' for the allocated
if (getLangOpts().ObjCAutoRefCount &&
AllocType.getObjCLifetime() == Qualifiers::OCL_None &&
AllocType->isObjCLifetimeType()) {
AllocType = Context.getLifetimeQualifiedType(AllocType,
AllocType->getObjCARCImplicitLifetime());
}
QualType ResultType = Context.getPointerType(AllocType);
if (ArraySize && ArraySize->getType()->isNonOverloadPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(ArraySize);
if (result.isInvalid()) return ExprError();
ArraySize = result.get();
}
// C++98 5.3.4p6: "The expression in a direct-new-declarator shall have
// integral or enumeration type with a non-negative value."
// C++11 [expr.new]p6: The expression [...] shall be of integral or unscoped
// enumeration type, or a class type for which a single non-explicit
// conversion function to integral or unscoped enumeration type exists.
// C++1y [expr.new]p6: The expression [...] is implicitly converted to
// std::size_t.
if (ArraySize && !ArraySize->isTypeDependent()) {
ExprResult ConvertedSize;
if (getLangOpts().CPlusPlus14) {
assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?");
ConvertedSize = PerformImplicitConversion(ArraySize, Context.getSizeType(),
AA_Converting);
if (!ConvertedSize.isInvalid() &&
ArraySize->getType()->getAs<RecordType>())
// Diagnose the compatibility of this conversion.
Diag(StartLoc, diag::warn_cxx98_compat_array_size_conversion)
<< ArraySize->getType() << 0 << "'size_t'";
} else {
class SizeConvertDiagnoser : public ICEConvertDiagnoser {
protected:
Expr *ArraySize;
public:
SizeConvertDiagnoser(Expr *ArraySize)
: ICEConvertDiagnoser(/*AllowScopedEnumerations*/false, false, false),
ArraySize(ArraySize) {}
SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
QualType T) override {
return S.Diag(Loc, diag::err_array_size_not_integral)
<< S.getLangOpts().CPlusPlus11 << T;
}
SemaDiagnosticBuilder diagnoseIncomplete(
Sema &S, SourceLocation Loc, QualType T) override {
return S.Diag(Loc, diag::err_array_size_incomplete_type)
<< T << ArraySize->getSourceRange();
}
SemaDiagnosticBuilder diagnoseExplicitConv(
Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
return S.Diag(Loc, diag::err_array_size_explicit_conversion) << T << ConvTy;
}
SemaDiagnosticBuilder noteExplicitConv(
Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
<< ConvTy->isEnumeralType() << ConvTy;
}
SemaDiagnosticBuilder diagnoseAmbiguous(
Sema &S, SourceLocation Loc, QualType T) override {
return S.Diag(Loc, diag::err_array_size_ambiguous_conversion) << T;
}
SemaDiagnosticBuilder noteAmbiguous(
Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
<< ConvTy->isEnumeralType() << ConvTy;
}
SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc,
QualType T,
QualType ConvTy) override {
return S.Diag(Loc,
S.getLangOpts().CPlusPlus11
? diag::warn_cxx98_compat_array_size_conversion
: diag::ext_array_size_conversion)
<< T << ConvTy->isEnumeralType() << ConvTy;
}
} SizeDiagnoser(ArraySize);
ConvertedSize = PerformContextualImplicitConversion(StartLoc, ArraySize,
SizeDiagnoser);
}
if (ConvertedSize.isInvalid())
return ExprError();
ArraySize = ConvertedSize.get();
QualType SizeType = ArraySize->getType();
if (!SizeType->isIntegralOrUnscopedEnumerationType())
return ExprError();
// C++98 [expr.new]p7:
// The expression in a direct-new-declarator shall have integral type
// with a non-negative value.
//
// Let's see if this is a constant < 0. If so, we reject it out of
// hand. Otherwise, if it's not a constant, we must have an unparenthesized
// array type.
//
// Note: such a construct has well-defined semantics in C++11: it throws
// std::bad_array_new_length.
if (!ArraySize->isValueDependent()) {
llvm::APSInt Value;
// We've already performed any required implicit conversion to integer or
// unscoped enumeration type.
if (ArraySize->isIntegerConstantExpr(Value, Context)) {
if (Value < llvm::APSInt(
llvm::APInt::getNullValue(Value.getBitWidth()),
Value.isUnsigned())) {
if (getLangOpts().CPlusPlus11)
Diag(ArraySize->getLocStart(),
diag::warn_typecheck_negative_array_new_size)
<< ArraySize->getSourceRange();
else
return ExprError(Diag(ArraySize->getLocStart(),
diag::err_typecheck_negative_array_size)
<< ArraySize->getSourceRange());
} else if (!AllocType->isDependentType()) {
unsigned ActiveSizeBits =
ConstantArrayType::getNumAddressingBits(Context, AllocType, Value);
if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
if (getLangOpts().CPlusPlus11)
Diag(ArraySize->getLocStart(),
diag::warn_array_new_too_large)
<< Value.toString(10)
<< ArraySize->getSourceRange();
else
return ExprError(Diag(ArraySize->getLocStart(),
diag::err_array_too_large)
<< Value.toString(10)
<< ArraySize->getSourceRange());
}
}
} else if (TypeIdParens.isValid()) {
// Can't have dynamic array size when the type-id is in parentheses.
Diag(ArraySize->getLocStart(), diag::ext_new_paren_array_nonconst)
<< ArraySize->getSourceRange()
<< FixItHint::CreateRemoval(TypeIdParens.getBegin())
<< FixItHint::CreateRemoval(TypeIdParens.getEnd());
TypeIdParens = SourceRange();
}
}
// Note that we do *not* convert the argument in any way. It can
// be signed, larger than size_t, whatever.
}
FunctionDecl *OperatorNew = nullptr;
FunctionDecl *OperatorDelete = nullptr;
if (!AllocType->isDependentType() &&
!Expr::hasAnyTypeDependentArguments(PlacementArgs) &&
FindAllocationFunctions(StartLoc,
SourceRange(PlacementLParen, PlacementRParen),
UseGlobal, AllocType, ArraySize, PlacementArgs,
OperatorNew, OperatorDelete))
return ExprError();
// If this is an array allocation, compute whether the usual array
// deallocation function for the type has a size_t parameter.
bool UsualArrayDeleteWantsSize = false;
if (ArraySize && !AllocType->isDependentType())
UsualArrayDeleteWantsSize
= doesUsualArrayDeleteWantSize(*this, StartLoc, AllocType);
SmallVector<Expr *, 8> AllPlaceArgs;
if (OperatorNew) {
const FunctionProtoType *Proto =
OperatorNew->getType()->getAs<FunctionProtoType>();
VariadicCallType CallType = Proto->isVariadic() ? VariadicFunction
: VariadicDoesNotApply;
// We've already converted the placement args, just fill in any default
// arguments. Skip the first parameter because we don't have a corresponding
// argument.
if (GatherArgumentsForCall(PlacementLParen, OperatorNew, Proto, 1,
PlacementArgs, AllPlaceArgs, CallType))
return ExprError();
if (!AllPlaceArgs.empty())
PlacementArgs = AllPlaceArgs;
// FIXME: This is wrong: PlacementArgs misses out the first (size) argument.
DiagnoseSentinelCalls(OperatorNew, PlacementLParen, PlacementArgs);
// FIXME: Missing call to CheckFunctionCall or equivalent
}
// Warn if the type is over-aligned and is being allocated by global operator
// new.
if (PlacementArgs.empty() && OperatorNew &&
(OperatorNew->isImplicit() ||
getSourceManager().isInSystemHeader(OperatorNew->getLocStart()))) {
if (unsigned Align = Context.getPreferredTypeAlign(AllocType.getTypePtr())){
unsigned SuitableAlign = Context.getTargetInfo().getSuitableAlign();
if (Align > SuitableAlign)
Diag(StartLoc, diag::warn_overaligned_type)
<< AllocType
<< unsigned(Align / Context.getCharWidth())
<< unsigned(SuitableAlign / Context.getCharWidth());
}
}
QualType InitType = AllocType;
// Array 'new' can't have any initializers except empty parentheses.
// Initializer lists are also allowed, in C++11. Rely on the parser for the
// dialect distinction.
if (ResultType->isArrayType() || ArraySize) {
if (!isLegalArrayNewInitializer(initStyle, Initializer)) {
SourceRange InitRange(Inits[0]->getLocStart(),
Inits[NumInits - 1]->getLocEnd());
Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
return ExprError();
}
if (InitListExpr *ILE = dyn_cast_or_null<InitListExpr>(Initializer)) {
// We do the initialization typechecking against the array type
// corresponding to the number of initializers + 1 (to also check
// default-initialization).
unsigned NumElements = ILE->getNumInits() + 1;
InitType = Context.getConstantArrayType(AllocType,
llvm::APInt(Context.getTypeSize(Context.getSizeType()), NumElements),
ArrayType::Normal, 0);
}
}
// If we can perform the initialization, and we've not already done so,
// do it now.
if (!AllocType->isDependentType() &&
!Expr::hasAnyTypeDependentArguments(
llvm::makeArrayRef(Inits, NumInits))) {
// C++11 [expr.new]p15:
// A new-expression that creates an object of type T initializes that
// object as follows:
InitializationKind Kind
// - If the new-initializer is omitted, the object is default-
// initialized (8.5); if no initialization is performed,
// the object has indeterminate value
= initStyle == CXXNewExpr::NoInit
? InitializationKind::CreateDefault(TypeRange.getBegin())
// - Otherwise, the new-initializer is interpreted according to the
// initialization rules of 8.5 for direct-initialization.
: initStyle == CXXNewExpr::ListInit
? InitializationKind::CreateDirectList(TypeRange.getBegin())
: InitializationKind::CreateDirect(TypeRange.getBegin(),
DirectInitRange.getBegin(),
DirectInitRange.getEnd());
InitializedEntity Entity
= InitializedEntity::InitializeNew(StartLoc, InitType);
InitializationSequence InitSeq(*this, Entity, Kind, MultiExprArg(Inits, NumInits));
ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
MultiExprArg(Inits, NumInits));
if (FullInit.isInvalid())
return ExprError();
// FullInit is our initializer; strip off CXXBindTemporaryExprs, because
// we don't want the initialized object to be destructed.
if (CXXBindTemporaryExpr *Binder =
dyn_cast_or_null<CXXBindTemporaryExpr>(FullInit.get()))
FullInit = Binder->getSubExpr();
Initializer = FullInit.get();
}
// Mark the new and delete operators as referenced.
if (OperatorNew) {
if (DiagnoseUseOfDecl(OperatorNew, StartLoc))
return ExprError();
MarkFunctionReferenced(StartLoc, OperatorNew);
}
if (OperatorDelete) {
if (DiagnoseUseOfDecl(OperatorDelete, StartLoc))
return ExprError();
MarkFunctionReferenced(StartLoc, OperatorDelete);
}
// C++0x [expr.new]p17:
// If the new expression creates an array of objects of class type,
// access and ambiguity control are done for the destructor.
QualType BaseAllocType = Context.getBaseElementType(AllocType);
if (ArraySize && !BaseAllocType->isDependentType()) {
if (const RecordType *BaseRecordType = BaseAllocType->getAs<RecordType>()) {
if (CXXDestructorDecl *dtor = LookupDestructor(
cast<CXXRecordDecl>(BaseRecordType->getDecl()))) {
MarkFunctionReferenced(StartLoc, dtor);
CheckDestructorAccess(StartLoc, dtor,
PDiag(diag::err_access_dtor)
<< BaseAllocType);
if (DiagnoseUseOfDecl(dtor, StartLoc))
return ExprError();
}
}
}
return new (Context)
CXXNewExpr(Context, UseGlobal, OperatorNew, OperatorDelete,
UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens,
ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo,
Range, DirectInitRange);
}
/// \brief Checks that a type is suitable as the allocated type
/// in a new-expression.
bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
SourceRange R) {
// C++ 5.3.4p1: "[The] type shall be a complete object type, but not an
// abstract class type or array thereof.
if (AllocType->isFunctionType())
return Diag(Loc, diag::err_bad_new_type)
<< AllocType << 0 << R;
else if (AllocType->isReferenceType())
return Diag(Loc, diag::err_bad_new_type)
<< AllocType << 1 << R;
else if (!AllocType->isDependentType() &&
RequireCompleteType(Loc, AllocType, diag::err_new_incomplete_type,R))
return true;
else if (RequireNonAbstractType(Loc, AllocType,
diag::err_allocation_of_abstract_type))
return true;
else if (AllocType->isVariablyModifiedType())
return Diag(Loc, diag::err_variably_modified_new_type)
<< AllocType;
else if (unsigned AddressSpace = AllocType.getAddressSpace())
return Diag(Loc, diag::err_address_space_qualified_new)
<< AllocType.getUnqualifiedType() << AddressSpace;
else if (getLangOpts().ObjCAutoRefCount) {
if (const ArrayType *AT = Context.getAsArrayType(AllocType)) {
QualType BaseAllocType = Context.getBaseElementType(AT);
if (BaseAllocType.getObjCLifetime() == Qualifiers::OCL_None &&
BaseAllocType->isObjCLifetimeType())
return Diag(Loc, diag::err_arc_new_array_without_ownership)
<< BaseAllocType;
}
}
return false;
}
/// \brief Determine whether the given function is a non-placement
/// deallocation function.
static bool isNonPlacementDeallocationFunction(Sema &S, FunctionDecl *FD) {
if (FD->isInvalidDecl())
return false;
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD))
return Method->isUsualDeallocationFunction();
if (FD->getOverloadedOperator() != OO_Delete &&
FD->getOverloadedOperator() != OO_Array_Delete)
return false;
if (FD->getNumParams() == 1)
return true;
return S.getLangOpts().SizedDeallocation && FD->getNumParams() == 2 &&
S.Context.hasSameUnqualifiedType(FD->getParamDecl(1)->getType(),
S.Context.getSizeType());
}
/// FindAllocationFunctions - Finds the overloads of operator new and delete
/// that are appropriate for the allocation.
bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
bool UseGlobal, QualType AllocType,
bool IsArray, MultiExprArg PlaceArgs,
FunctionDecl *&OperatorNew,
FunctionDecl *&OperatorDelete) {
// --- Choosing an allocation function ---
// C++ 5.3.4p8 - 14 & 18
// 1) If UseGlobal is true, only look in the global scope. Else, also look
// in the scope of the allocated class.
// 2) If an array size is given, look for operator new[], else look for
// operator new.
// 3) The first argument is always size_t. Append the arguments from the
// placement form.
SmallVector<Expr*, 8> AllocArgs(1 + PlaceArgs.size());
// We don't care about the actual value of this argument.
// FIXME: Should the Sema create the expression and embed it in the syntax
// tree? Or should the consumer just recalculate the value?
IntegerLiteral Size(Context, llvm::APInt::getNullValue(
Context.getTargetInfo().getPointerWidth(0)),
Context.getSizeType(),
SourceLocation());
AllocArgs[0] = &Size;
std::copy(PlaceArgs.begin(), PlaceArgs.end(), AllocArgs.begin() + 1);
// C++ [expr.new]p8:
// If the allocated type is a non-array type, the allocation
// function's name is operator new and the deallocation function's
// name is operator delete. If the allocated type is an array
// type, the allocation function's name is operator new[] and the
// deallocation function's name is operator delete[].
DeclarationName NewName = Context.DeclarationNames.getCXXOperatorName(
IsArray ? OO_Array_New : OO_New);
DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
IsArray ? OO_Array_Delete : OO_Delete);
QualType AllocElemType = Context.getBaseElementType(AllocType);
if (AllocElemType->isRecordType() && !UseGlobal) {
CXXRecordDecl *Record
= cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
if (FindAllocationOverload(StartLoc, Range, NewName, AllocArgs, Record,
/*AllowMissing=*/true, OperatorNew))
return true;
}
if (!OperatorNew) {
// Didn't find a member overload. Look for a global one.
DeclareGlobalNewDelete();
DeclContext *TUDecl = Context.getTranslationUnitDecl();
bool FallbackEnabled = IsArray && Context.getLangOpts().MSVCCompat;
if (FindAllocationOverload(StartLoc, Range, NewName, AllocArgs, TUDecl,
/*AllowMissing=*/FallbackEnabled, OperatorNew,
/*Diagnose=*/!FallbackEnabled)) {
if (!FallbackEnabled)
return true;
// MSVC will fall back on trying to find a matching global operator new
// if operator new[] cannot be found. Also, MSVC will leak by not
// generating a call to operator delete or operator delete[], but we
// will not replicate that bug.
NewName = Context.DeclarationNames.getCXXOperatorName(OO_New);
DeleteName = Context.DeclarationNames.getCXXOperatorName(OO_Delete);
if (FindAllocationOverload(StartLoc, Range, NewName, AllocArgs, TUDecl,
/*AllowMissing=*/false, OperatorNew))
return true;
}
}
// We don't need an operator delete if we're running under
// -fno-exceptions.
if (!getLangOpts().Exceptions) {
OperatorDelete = nullptr;
return false;
}
// C++ [expr.new]p19:
//
// If the new-expression begins with a unary :: operator, the
// deallocation function's name is looked up in the global
// scope. Otherwise, if the allocated type is a class type T or an
// array thereof, the deallocation function's name is looked up in
// the scope of T. If this lookup fails to find the name, or if
// the allocated type is not a class type or array thereof, the
// deallocation function's name is looked up in the global scope.
LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName);
if (AllocElemType->isRecordType() && !UseGlobal) {
CXXRecordDecl *RD
= cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
LookupQualifiedName(FoundDelete, RD);
}
if (FoundDelete.isAmbiguous())
return true; // FIXME: clean up expressions?
if (FoundDelete.empty()) {
DeclareGlobalNewDelete();
LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl());
}
FoundDelete.suppressDiagnostics();
SmallVector<std::pair<DeclAccessPair,FunctionDecl*>, 2> Matches;
// Whether we're looking for a placement operator delete is dictated
// by whether we selected a placement operator new, not by whether
// we had explicit placement arguments. This matters for things like
// struct A { void *operator new(size_t, int = 0); ... };
// A *a = new A()
bool isPlacementNew = (!PlaceArgs.empty() || OperatorNew->param_size() != 1);
if (isPlacementNew) {
// C++ [expr.new]p20:
// A declaration of a placement deallocation function matches the
// declaration of a placement allocation function if it has the
// same number of parameters and, after parameter transformations
// (8.3.5), all parameter types except the first are
// identical. [...]
//
// To perform this comparison, we compute the function type that
// the deallocation function should have, and use that type both
// for template argument deduction and for comparison purposes.
//
// FIXME: this comparison should ignore CC and the like.
QualType ExpectedFunctionType;
{
const FunctionProtoType *Proto
= OperatorNew->getType()->getAs<FunctionProtoType>();
SmallVector<QualType, 4> ArgTypes;
ArgTypes.push_back(Context.VoidPtrTy);
for (unsigned I = 1, N = Proto->getNumParams(); I < N; ++I)
ArgTypes.push_back(Proto->getParamType(I));
FunctionProtoType::ExtProtoInfo EPI;
EPI.Variadic = Proto->isVariadic();
ExpectedFunctionType
= Context.getFunctionType(Context.VoidTy, ArgTypes, EPI);
}
for (LookupResult::iterator D = FoundDelete.begin(),
DEnd = FoundDelete.end();
D != DEnd; ++D) {
FunctionDecl *Fn = nullptr;
if (FunctionTemplateDecl *FnTmpl
= dyn_cast<FunctionTemplateDecl>((*D)->getUnderlyingDecl())) {
// Perform template argument deduction to try to match the
// expected function type.
TemplateDeductionInfo Info(StartLoc);
if (DeduceTemplateArguments(FnTmpl, nullptr, ExpectedFunctionType, Fn,
Info))
continue;
} else
Fn = cast<FunctionDecl>((*D)->getUnderlyingDecl());
if (Context.hasSameType(Fn->getType(), ExpectedFunctionType))
Matches.push_back(std::make_pair(D.getPair(), Fn));
}
} else {
// C++ [expr.new]p20:
// [...] Any non-placement deallocation function matches a
// non-placement allocation function. [...]
for (LookupResult::iterator D = FoundDelete.begin(),
DEnd = FoundDelete.end();
D != DEnd; ++D) {
if (FunctionDecl *Fn = dyn_cast<FunctionDecl>((*D)->getUnderlyingDecl()))
if (isNonPlacementDeallocationFunction(*this, Fn))
Matches.push_back(std::make_pair(D.getPair(), Fn));
}
// C++1y [expr.new]p22:
// For a non-placement allocation function, the normal deallocation
// function lookup is used
// C++1y [expr.delete]p?:
// If [...] deallocation function lookup finds both a usual deallocation
// function with only a pointer parameter and a usual deallocation
// function with both a pointer parameter and a size parameter, then the
// selected deallocation function shall be the one with two parameters.
// Otherwise, the selected deallocation function shall be the function
// with one parameter.
if (getLangOpts().SizedDeallocation && Matches.size() == 2) {
if (Matches[0].second->getNumParams() == 1)
Matches.erase(Matches.begin());
else
Matches.erase(Matches.begin() + 1);
assert(Matches[0].second->getNumParams() == 2 &&
"found an unexpected usual deallocation function");
}
}
// C++ [expr.new]p20:
// [...] If the lookup finds a single matching deallocation
// function, that function will be called; otherwise, no
// deallocation function will be called.
if (Matches.size() == 1) {
OperatorDelete = Matches[0].second;
// C++0x [expr.new]p20:
// If the lookup finds the two-parameter form of a usual
// deallocation function (3.7.4.2) and that function, considered
// as a placement deallocation function, would have been
// selected as a match for the allocation function, the program
// is ill-formed.
if (!PlaceArgs.empty() && getLangOpts().CPlusPlus11 &&
isNonPlacementDeallocationFunction(*this, OperatorDelete)) {
Diag(StartLoc, diag::err_placement_new_non_placement_delete)
<< SourceRange(PlaceArgs.front()->getLocStart(),
PlaceArgs.back()->getLocEnd());
if (!OperatorDelete->isImplicit())
Diag(OperatorDelete->getLocation(), diag::note_previous_decl)
<< DeleteName;
} else {
CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(),
Matches[0].first);
}
}
return false;
}
/// \brief Find an fitting overload for the allocation function
/// in the specified scope.
///
/// \param StartLoc The location of the 'new' token.
/// \param Range The range of the placement arguments.
/// \param Name The name of the function ('operator new' or 'operator new[]').
/// \param Args The placement arguments specified.
/// \param Ctx The scope in which we should search; either a class scope or the
/// translation unit.
/// \param AllowMissing If \c true, report an error if we can't find any
/// allocation functions. Otherwise, succeed but don't fill in \p
/// Operator.
/// \param Operator Filled in with the found allocation function. Unchanged if
/// no allocation function was found.
/// \param Diagnose If \c true, issue errors if the allocation function is not
/// usable.
bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
DeclarationName Name, MultiExprArg Args,
DeclContext *Ctx,
bool AllowMissing, FunctionDecl *&Operator,
bool Diagnose) {
LookupResult R(*this, Name, StartLoc, LookupOrdinaryName);
LookupQualifiedName(R, Ctx);
if (R.empty()) {
if (AllowMissing || !Diagnose)
return false;
return Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
<< Name << Range;
}
if (R.isAmbiguous())
return true;
R.suppressDiagnostics();
OverloadCandidateSet Candidates(StartLoc, OverloadCandidateSet::CSK_Normal);
for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end();
Alloc != AllocEnd; ++Alloc) {
// Even member operator new/delete are implicitly treated as
// static, so don't use AddMemberCandidate.
NamedDecl *D = (*Alloc)->getUnderlyingDecl();
if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl>(D)) {
AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(),
/*ExplicitTemplateArgs=*/nullptr,
Args, Candidates,
/*SuppressUserConversions=*/false);
continue;
}
FunctionDecl *Fn = cast<FunctionDecl>(D);
AddOverloadCandidate(Fn, Alloc.getPair(), Args, Candidates,
/*SuppressUserConversions=*/false);
}
// Do the resolution.
OverloadCandidateSet::iterator Best;
switch (Candidates.BestViableFunction(*this, StartLoc, Best)) {
case OR_Success: {
// Got one!
FunctionDecl *FnDecl = Best->Function;
if (CheckAllocationAccess(StartLoc, Range, R.getNamingClass(),
Best->FoundDecl, Diagnose) == AR_inaccessible)
return true;
Operator = FnDecl;
return false;
}
case OR_No_Viable_Function:
if (Diagnose) {
Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
<< Name << Range;
Candidates.NoteCandidates(*this, OCD_AllCandidates, Args);
}
return true;
case OR_Ambiguous:
if (Diagnose) {
Diag(StartLoc, diag::err_ovl_ambiguous_call)
<< Name << Range;
Candidates.NoteCandidates(*this, OCD_ViableCandidates, Args);
}
return true;
case OR_Deleted: {
if (Diagnose) {
Diag(StartLoc, diag::err_ovl_deleted_call)
<< Best->Function->isDeleted()
<< Name
<< getDeletedOrUnavailableSuffix(Best->Function)
<< Range;
Candidates.NoteCandidates(*this, OCD_AllCandidates, Args);
}
return true;
}
}
llvm_unreachable("Unreachable, bad result from BestViableFunction");
}
/// DeclareGlobalNewDelete - Declare the global forms of operator new and
/// delete. These are:
/// @code
/// // C++03:
/// void* operator new(std::size_t) throw(std::bad_alloc);
/// void* operator new[](std::size_t) throw(std::bad_alloc);
/// void operator delete(void *) throw();
/// void operator delete[](void *) throw();
/// // C++11:
/// void* operator new(std::size_t);
/// void* operator new[](std::size_t);
/// void operator delete(void *) noexcept;
/// void operator delete[](void *) noexcept;
/// // C++1y:
/// void* operator new(std::size_t);
/// void* operator new[](std::size_t);
/// void operator delete(void *) noexcept;
/// void operator delete[](void *) noexcept;
/// void operator delete(void *, std::size_t) noexcept;
/// void operator delete[](void *, std::size_t) noexcept;
/// @endcode
/// Note that the placement and nothrow forms of new are *not* implicitly
/// declared. Their use requires including \<new\>.
void Sema::DeclareGlobalNewDelete() {
if (GlobalNewDeleteDeclared)
return;
// C++ [basic.std.dynamic]p2:
// [...] The following allocation and deallocation functions (18.4) are
// implicitly declared in global scope in each translation unit of a
// program
//
// C++03:
// void* operator new(std::size_t) throw(std::bad_alloc);
// void* operator new[](std::size_t) throw(std::bad_alloc);
// void operator delete(void*) throw();
// void operator delete[](void*) throw();
// C++11:
// void* operator new(std::size_t);
// void* operator new[](std::size_t);
// void operator delete(void*) noexcept;
// void operator delete[](void*) noexcept;
// C++1y:
// void* operator new(std::size_t);
// void* operator new[](std::size_t);
// void operator delete(void*) noexcept;
// void operator delete[](void*) noexcept;
// void operator delete(void*, std::size_t) noexcept;
// void operator delete[](void*, std::size_t) noexcept;
//
// These implicit declarations introduce only the function names operator
// new, operator new[], operator delete, operator delete[].
//
// Here, we need to refer to std::bad_alloc, so we will implicitly declare
// "std" or "bad_alloc" as necessary to form the exception specification.
// However, we do not make these implicit declarations visible to name
// lookup.
if (!StdBadAlloc && !getLangOpts().CPlusPlus11) {
// The "std::bad_alloc" class has not yet been declared, so build it
// implicitly.
StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class,
getOrCreateStdNamespace(),
SourceLocation(), SourceLocation(),
&PP.getIdentifierTable().get("bad_alloc"),
nullptr);
getStdBadAlloc()->setImplicit(true);
}
GlobalNewDeleteDeclared = true;
QualType VoidPtr = Context.getPointerType(Context.VoidTy);
QualType SizeT = Context.getSizeType();
bool AssumeSaneOperatorNew = getLangOpts().AssumeSaneOperatorNew;
DeclareGlobalAllocationFunction(
Context.DeclarationNames.getCXXOperatorName(OO_New),
VoidPtr, SizeT, QualType(), AssumeSaneOperatorNew);
DeclareGlobalAllocationFunction(
Context.DeclarationNames.getCXXOperatorName(OO_Array_New),
VoidPtr, SizeT, QualType(), AssumeSaneOperatorNew);
DeclareGlobalAllocationFunction(
Context.DeclarationNames.getCXXOperatorName(OO_Delete),
Context.VoidTy, VoidPtr);
DeclareGlobalAllocationFunction(
Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete),
Context.VoidTy, VoidPtr);
if (getLangOpts().SizedDeallocation) {
DeclareGlobalAllocationFunction(
Context.DeclarationNames.getCXXOperatorName(OO_Delete),
Context.VoidTy, VoidPtr, Context.getSizeType());
DeclareGlobalAllocationFunction(
Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete),
Context.VoidTy, VoidPtr, Context.getSizeType());
}
}
/// DeclareGlobalAllocationFunction - Declares a single implicit global
/// allocation function if it doesn't already exist.
void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
QualType Return,
QualType Param1, QualType Param2,
bool AddRestrictAttr) {
DeclContext *GlobalCtx = Context.getTranslationUnitDecl();
unsigned NumParams = Param2.isNull() ? 1 : 2;
// Check if this function is already declared.
DeclContext::lookup_result R = GlobalCtx->lookup(Name);
for (DeclContext::lookup_iterator Alloc = R.begin(), AllocEnd = R.end();
Alloc != AllocEnd; ++Alloc) {
// Only look at non-template functions, as it is the predefined,
// non-templated allocation function we are trying to declare here.
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*Alloc)) {
if (Func->getNumParams() == NumParams) {
QualType InitialParam1Type =
Context.getCanonicalType(Func->getParamDecl(0)
->getType().getUnqualifiedType());
QualType InitialParam2Type =
NumParams == 2
? Context.getCanonicalType(Func->getParamDecl(1)
->getType().getUnqualifiedType())
: QualType();
// FIXME: Do we need to check for default arguments here?
if (InitialParam1Type == Param1 &&
(NumParams == 1 || InitialParam2Type == Param2)) {
if (AddRestrictAttr && !Func->hasAttr<RestrictAttr>())
Func->addAttr(RestrictAttr::CreateImplicit(
Context, RestrictAttr::GNU_malloc));
// Make the function visible to name lookup, even if we found it in
// an unimported module. It either is an implicitly-declared global
// allocation function, or is suppressing that function.
Func->setHidden(false);
return;
}
}
}
}
FunctionProtoType::ExtProtoInfo EPI;
QualType BadAllocType;
bool HasBadAllocExceptionSpec
= (Name.getCXXOverloadedOperator() == OO_New ||
Name.getCXXOverloadedOperator() == OO_Array_New);
if (HasBadAllocExceptionSpec) {
if (!getLangOpts().CPlusPlus11) {
BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
assert(StdBadAlloc && "Must have std::bad_alloc declared");
EPI.ExceptionSpec.Type = EST_Dynamic;
EPI.ExceptionSpec.Exceptions = llvm::makeArrayRef(BadAllocType);
}
} else {
EPI.ExceptionSpec =
getLangOpts().CPlusPlus11 ? EST_BasicNoexcept : EST_DynamicNone;
}
QualType Params[] = { Param1, Param2 };
QualType FnType = Context.getFunctionType(
Return, llvm::makeArrayRef(Params, NumParams), EPI);
FunctionDecl *Alloc =
FunctionDecl::Create(Context, GlobalCtx, SourceLocation(),
SourceLocation(), Name,
FnType, /*TInfo=*/nullptr, SC_None, false, true);
Alloc->setImplicit();
// Implicit sized deallocation functions always have default visibility.
Alloc->addAttr(VisibilityAttr::CreateImplicit(Context,
VisibilityAttr::Default));
if (AddRestrictAttr)
Alloc->addAttr(
RestrictAttr::CreateImplicit(Context, RestrictAttr::GNU_malloc));
ParmVarDecl *ParamDecls[2];
for (unsigned I = 0; I != NumParams; ++I) {
ParamDecls[I] = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
SourceLocation(), nullptr,
Params[I], /*TInfo=*/nullptr,
SC_None, nullptr);
ParamDecls[I]->setImplicit();
}
Alloc->setParams(llvm::makeArrayRef(ParamDecls, NumParams));
Context.getTranslationUnitDecl()->addDecl(Alloc);
IdResolver.tryAddTopLevelDecl(Alloc, Name);
}
FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc,
bool CanProvideSize,
DeclarationName Name) {
DeclareGlobalNewDelete();
LookupResult FoundDelete(*this, Name, StartLoc, LookupOrdinaryName);
LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl());
// C++ [expr.new]p20:
// [...] Any non-placement deallocation function matches a
// non-placement allocation function. [...]
llvm::SmallVector<FunctionDecl*, 2> Matches;
for (LookupResult::iterator D = FoundDelete.begin(),
DEnd = FoundDelete.end();
D != DEnd; ++D) {
if (FunctionDecl *Fn = dyn_cast<FunctionDecl>(*D))
if (isNonPlacementDeallocationFunction(*this, Fn))
Matches.push_back(Fn);
}
// C++1y [expr.delete]p?:
// If the type is complete and deallocation function lookup finds both a
// usual deallocation function with only a pointer parameter and a usual
// deallocation function with both a pointer parameter and a size
// parameter, then the selected deallocation function shall be the one
// with two parameters. Otherwise, the selected deallocation function
// shall be the function with one parameter.
if (getLangOpts().SizedDeallocation && Matches.size() == 2) {
unsigned NumArgs = CanProvideSize ? 2 : 1;
if (Matches[0]->getNumParams() != NumArgs)
Matches.erase(Matches.begin());
else
Matches.erase(Matches.begin() + 1);
assert(Matches[0]->getNumParams() == NumArgs &&
"found an unexpected usual deallocation function");
}
if (getLangOpts().CUDA && getLangOpts().CUDATargetOverloads)
EraseUnwantedCUDAMatches(dyn_cast<FunctionDecl>(CurContext), Matches);
assert(Matches.size() == 1 &&
"unexpectedly have multiple usual deallocation functions");
return Matches.front();
}
bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
DeclarationName Name,
FunctionDecl* &Operator, bool Diagnose) {
LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName);
// Try to find operator delete/operator delete[] in class scope.
LookupQualifiedName(Found, RD);
if (Found.isAmbiguous())
return true;
Found.suppressDiagnostics();
SmallVector<DeclAccessPair,4> Matches;
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
F != FEnd; ++F) {
NamedDecl *ND = (*F)->getUnderlyingDecl();
// Ignore template operator delete members from the check for a usual
// deallocation function.
if (isa<FunctionTemplateDecl>(ND))
continue;
if (cast<CXXMethodDecl>(ND)->isUsualDeallocationFunction())
Matches.push_back(F.getPair());
}
if (getLangOpts().CUDA && getLangOpts().CUDATargetOverloads)
EraseUnwantedCUDAMatches(dyn_cast<FunctionDecl>(CurContext), Matches);
// There's exactly one suitable operator; pick it.
if (Matches.size() == 1) {
Operator = cast<CXXMethodDecl>(Matches[0]->getUnderlyingDecl());
if (Operator->isDeleted()) {
if (Diagnose) {
Diag(StartLoc, diag::err_deleted_function_use);
NoteDeletedFunction(Operator);
}
return true;
}
if (CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
Matches[0], Diagnose) == AR_inaccessible)
return true;
return false;
// We found multiple suitable operators; complain about the ambiguity.
} else if (!Matches.empty()) {
if (Diagnose) {
Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
<< Name << RD;
for (SmallVectorImpl<DeclAccessPair>::iterator
F = Matches.begin(), FEnd = Matches.end(); F != FEnd; ++F)
Diag((*F)->getUnderlyingDecl()->getLocation(),
diag::note_member_declared_here) << Name;
}
return true;
}
// We did find operator delete/operator delete[] declarations, but
// none of them were suitable.
if (!Found.empty()) {
if (Diagnose) {
Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
<< Name << RD;
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
F != FEnd; ++F)
Diag((*F)->getUnderlyingDecl()->getLocation(),
diag::note_member_declared_here) << Name;
}
return true;
}
Operator = nullptr;
return false;
}
namespace {
/// \brief Checks whether delete-expression, and new-expression used for
/// initializing deletee have the same array form.
class MismatchingNewDeleteDetector {
public:
enum MismatchResult {
/// Indicates that there is no mismatch or a mismatch cannot be proven.
NoMismatch,
/// Indicates that variable is initialized with mismatching form of \a new.
VarInitMismatches,
/// Indicates that member is initialized with mismatching form of \a new.
MemberInitMismatches,
/// Indicates that 1 or more constructors' definitions could not been
/// analyzed, and they will be checked again at the end of translation unit.
AnalyzeLater
};
/// \param EndOfTU True, if this is the final analysis at the end of
/// translation unit. False, if this is the initial analysis at the point
/// delete-expression was encountered.
explicit MismatchingNewDeleteDetector(bool EndOfTU)
: IsArrayForm(false), Field(nullptr), EndOfTU(EndOfTU),
HasUndefinedConstructors(false) {}
/// \brief Checks whether pointee of a delete-expression is initialized with
/// matching form of new-expression.
///
/// If return value is \c VarInitMismatches or \c MemberInitMismatches at the
/// point where delete-expression is encountered, then a warning will be
/// issued immediately. If return value is \c AnalyzeLater at the point where
/// delete-expression is seen, then member will be analyzed at the end of
/// translation unit. \c AnalyzeLater is returned iff at least one constructor
/// couldn't be analyzed. If at least one constructor initializes the member
/// with matching type of new, the return value is \c NoMismatch.
MismatchResult analyzeDeleteExpr(const CXXDeleteExpr *DE);
/// \brief Analyzes a class member.
/// \param Field Class member to analyze.
/// \param DeleteWasArrayForm Array form-ness of the delete-expression used
/// for deleting the \p Field.
MismatchResult analyzeField(FieldDecl *Field, bool DeleteWasArrayForm);
/// List of mismatching new-expressions used for initialization of the pointee
llvm::SmallVector<const CXXNewExpr *, 4> NewExprs;
/// Indicates whether delete-expression was in array form.
bool IsArrayForm;
FieldDecl *Field;
private:
const bool EndOfTU;
/// \brief Indicates that there is at least one constructor without body.
bool HasUndefinedConstructors;
/// \brief Returns \c CXXNewExpr from given initialization expression.
/// \param E Expression used for initializing pointee in delete-expression.
/// E can be a single-element \c InitListExpr consisting of new-expression.
const CXXNewExpr *getNewExprFromInitListOrExpr(const Expr *E);
/// \brief Returns whether member is initialized with mismatching form of
/// \c new either by the member initializer or in-class initialization.
///
/// If bodies of all constructors are not visible at the end of translation
/// unit or at least one constructor initializes member with the matching
/// form of \c new, mismatch cannot be proven, and this function will return
/// \c NoMismatch.
MismatchResult analyzeMemberExpr(const MemberExpr *ME);
/// \brief Returns whether variable is initialized with mismatching form of
/// \c new.
///
/// If variable is initialized with matching form of \c new or variable is not
/// initialized with a \c new expression, this function will return true.
/// If variable is initialized with mismatching form of \c new, returns false.
/// \param D Variable to analyze.
bool hasMatchingVarInit(const DeclRefExpr *D);
/// \brief Checks whether the constructor initializes pointee with mismatching
/// form of \c new.
///
/// Returns true, if member is initialized with matching form of \c new in
/// member initializer list. Returns false, if member is initialized with the
/// matching form of \c new in this constructor's initializer or given
/// constructor isn't defined at the point where delete-expression is seen, or
/// member isn't initialized by the constructor.
bool hasMatchingNewInCtor(const CXXConstructorDecl *CD);
/// \brief Checks whether member is initialized with matching form of
/// \c new in member initializer list.
bool hasMatchingNewInCtorInit(const CXXCtorInitializer *CI);
/// Checks whether member is initialized with mismatching form of \c new by
/// in-class initializer.
MismatchResult analyzeInClassInitializer();
};
}
MismatchingNewDeleteDetector::MismatchResult
MismatchingNewDeleteDetector::analyzeDeleteExpr(const CXXDeleteExpr *DE) {
NewExprs.clear();
assert(DE && "Expected delete-expression");
IsArrayForm = DE->isArrayForm();
const Expr *E = DE->getArgument()->IgnoreParenImpCasts();
if (const MemberExpr *ME = dyn_cast<const MemberExpr>(E)) {
return analyzeMemberExpr(ME);
} else if (const DeclRefExpr *D = dyn_cast<const DeclRefExpr>(E)) {
if (!hasMatchingVarInit(D))
return VarInitMismatches;
}
return NoMismatch;
}
const CXXNewExpr *
MismatchingNewDeleteDetector::getNewExprFromInitListOrExpr(const Expr *E) {
assert(E != nullptr && "Expected a valid initializer expression");
E = E->IgnoreParenImpCasts();
if (const InitListExpr *ILE = dyn_cast<const InitListExpr>(E)) {
if (ILE->getNumInits() == 1)
E = dyn_cast<const CXXNewExpr>(ILE->getInit(0)->IgnoreParenImpCasts());
}
return dyn_cast_or_null<const CXXNewExpr>(E);
}
bool MismatchingNewDeleteDetector::hasMatchingNewInCtorInit(
const CXXCtorInitializer *CI) {
const CXXNewExpr *NE = nullptr;
if (Field == CI->getMember() &&
(NE = getNewExprFromInitListOrExpr(CI->getInit()))) {
if (NE->isArray() == IsArrayForm)
return true;
else
NewExprs.push_back(NE);
}
return false;
}
bool MismatchingNewDeleteDetector::hasMatchingNewInCtor(
const CXXConstructorDecl *CD) {
if (CD->isImplicit())
return false;
const FunctionDecl *Definition = CD;
if (!CD->isThisDeclarationADefinition() && !CD->isDefined(Definition)) {
HasUndefinedConstructors = true;
return EndOfTU;
}
for (const auto *CI : cast<const CXXConstructorDecl>(Definition)->inits()) {
if (hasMatchingNewInCtorInit(CI))