10b57cec5SDimitry Andric //===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// Implements semantic analysis for C++ expressions.
110b57cec5SDimitry Andric ///
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "TreeTransform.h"
150b57cec5SDimitry Andric #include "TypeLocBuilder.h"
160b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
170b57cec5SDimitry Andric #include "clang/AST/ASTLambda.h"
180b57cec5SDimitry Andric #include "clang/AST/CXXInheritance.h"
190b57cec5SDimitry Andric #include "clang/AST/CharUnits.h"
200b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
210b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
228a4dda33SDimitry Andric #include "clang/AST/ExprConcepts.h"
230b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h"
240b57cec5SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
25bdd1243dSDimitry Andric #include "clang/AST/Type.h"
260b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h"
270b57cec5SDimitry Andric #include "clang/Basic/AlignedAllocation.h"
2881ad6265SDimitry Andric #include "clang/Basic/DiagnosticSema.h"
290b57cec5SDimitry Andric #include "clang/Basic/PartialDiagnostic.h"
300b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
31bdd1243dSDimitry Andric #include "clang/Basic/TokenKinds.h"
3281ad6265SDimitry Andric #include "clang/Basic/TypeTraits.h"
330b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
340b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h"
3506c3fb27SDimitry Andric #include "clang/Sema/EnterExpressionEvaluationContext.h"
360b57cec5SDimitry Andric #include "clang/Sema/Initialization.h"
370b57cec5SDimitry Andric #include "clang/Sema/Lookup.h"
380b57cec5SDimitry Andric #include "clang/Sema/ParsedTemplate.h"
390b57cec5SDimitry Andric #include "clang/Sema/Scope.h"
400b57cec5SDimitry Andric #include "clang/Sema/ScopeInfo.h"
4181ad6265SDimitry Andric #include "clang/Sema/SemaInternal.h"
420b57cec5SDimitry Andric #include "clang/Sema/SemaLambda.h"
4381ad6265SDimitry Andric #include "clang/Sema/Template.h"
440b57cec5SDimitry Andric #include "clang/Sema/TemplateDeduction.h"
450b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
460b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
4706c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h"
480b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
4981ad6265SDimitry Andric #include "llvm/Support/TypeSize.h"
50bdd1243dSDimitry Andric #include <optional>
510b57cec5SDimitry Andric using namespace clang;
520b57cec5SDimitry Andric using namespace sema;
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric /// Handle the result of the special case name lookup for inheriting
550b57cec5SDimitry Andric /// constructor declarations. 'NS::X::X' and 'NS::X<...>::X' are treated as
560b57cec5SDimitry Andric /// constructor names in member using declarations, even if 'X' is not the
570b57cec5SDimitry Andric /// name of the corresponding type.
getInheritingConstructorName(CXXScopeSpec & SS,SourceLocation NameLoc,IdentifierInfo & Name)580b57cec5SDimitry Andric ParsedType Sema::getInheritingConstructorName(CXXScopeSpec &SS,
590b57cec5SDimitry Andric                                               SourceLocation NameLoc,
600b57cec5SDimitry Andric                                               IdentifierInfo &Name) {
610b57cec5SDimitry Andric   NestedNameSpecifier *NNS = SS.getScopeRep();
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   // Convert the nested-name-specifier into a type.
640b57cec5SDimitry Andric   QualType Type;
650b57cec5SDimitry Andric   switch (NNS->getKind()) {
660b57cec5SDimitry Andric   case NestedNameSpecifier::TypeSpec:
670b57cec5SDimitry Andric   case NestedNameSpecifier::TypeSpecWithTemplate:
680b57cec5SDimitry Andric     Type = QualType(NNS->getAsType(), 0);
690b57cec5SDimitry Andric     break;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   case NestedNameSpecifier::Identifier:
720b57cec5SDimitry Andric     // Strip off the last layer of the nested-name-specifier and build a
730b57cec5SDimitry Andric     // typename type for it.
740b57cec5SDimitry Andric     assert(NNS->getAsIdentifier() == &Name && "not a constructor name");
755f757f3fSDimitry Andric     Type = Context.getDependentNameType(
765f757f3fSDimitry Andric         ElaboratedTypeKeyword::None, NNS->getPrefix(), NNS->getAsIdentifier());
770b57cec5SDimitry Andric     break;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   case NestedNameSpecifier::Global:
800b57cec5SDimitry Andric   case NestedNameSpecifier::Super:
810b57cec5SDimitry Andric   case NestedNameSpecifier::Namespace:
820b57cec5SDimitry Andric   case NestedNameSpecifier::NamespaceAlias:
830b57cec5SDimitry Andric     llvm_unreachable("Nested name specifier is not a type for inheriting ctor");
840b57cec5SDimitry Andric   }
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   // This reference to the type is located entirely at the location of the
870b57cec5SDimitry Andric   // final identifier in the qualified-id.
880b57cec5SDimitry Andric   return CreateParsedType(Type,
890b57cec5SDimitry Andric                           Context.getTrivialTypeSourceInfo(Type, NameLoc));
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric 
getConstructorName(IdentifierInfo & II,SourceLocation NameLoc,Scope * S,CXXScopeSpec & SS,bool EnteringContext)920b57cec5SDimitry Andric ParsedType Sema::getConstructorName(IdentifierInfo &II,
930b57cec5SDimitry Andric                                     SourceLocation NameLoc,
940b57cec5SDimitry Andric                                     Scope *S, CXXScopeSpec &SS,
950b57cec5SDimitry Andric                                     bool EnteringContext) {
960b57cec5SDimitry Andric   CXXRecordDecl *CurClass = getCurrentClass(S, &SS);
970b57cec5SDimitry Andric   assert(CurClass && &II == CurClass->getIdentifier() &&
980b57cec5SDimitry Andric          "not a constructor name");
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   // When naming a constructor as a member of a dependent context (eg, in a
1010b57cec5SDimitry Andric   // friend declaration or an inherited constructor declaration), form an
1020b57cec5SDimitry Andric   // unresolved "typename" type.
1030b57cec5SDimitry Andric   if (CurClass->isDependentContext() && !EnteringContext && SS.getScopeRep()) {
1045f757f3fSDimitry Andric     QualType T = Context.getDependentNameType(ElaboratedTypeKeyword::None,
1055f757f3fSDimitry Andric                                               SS.getScopeRep(), &II);
1060b57cec5SDimitry Andric     return ParsedType::make(T);
1070b57cec5SDimitry Andric   }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   if (SS.isNotEmpty() && RequireCompleteDeclContext(SS, CurClass))
1100b57cec5SDimitry Andric     return ParsedType();
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   // Find the injected-class-name declaration. Note that we make no attempt to
1130b57cec5SDimitry Andric   // diagnose cases where the injected-class-name is shadowed: the only
1140b57cec5SDimitry Andric   // declaration that can validly shadow the injected-class-name is a
1150b57cec5SDimitry Andric   // non-static data member, and if the class contains both a non-static data
1160b57cec5SDimitry Andric   // member and a constructor then it is ill-formed (we check that in
1170b57cec5SDimitry Andric   // CheckCompletedCXXClass).
1180b57cec5SDimitry Andric   CXXRecordDecl *InjectedClassName = nullptr;
1190b57cec5SDimitry Andric   for (NamedDecl *ND : CurClass->lookup(&II)) {
1200b57cec5SDimitry Andric     auto *RD = dyn_cast<CXXRecordDecl>(ND);
1210b57cec5SDimitry Andric     if (RD && RD->isInjectedClassName()) {
1220b57cec5SDimitry Andric       InjectedClassName = RD;
1230b57cec5SDimitry Andric       break;
1240b57cec5SDimitry Andric     }
1250b57cec5SDimitry Andric   }
1260b57cec5SDimitry Andric   if (!InjectedClassName) {
1270b57cec5SDimitry Andric     if (!CurClass->isInvalidDecl()) {
1280b57cec5SDimitry Andric       // FIXME: RequireCompleteDeclContext doesn't check dependent contexts
1290b57cec5SDimitry Andric       // properly. Work around it here for now.
1300b57cec5SDimitry Andric       Diag(SS.getLastQualifierNameLoc(),
1310b57cec5SDimitry Andric            diag::err_incomplete_nested_name_spec) << CurClass << SS.getRange();
1320b57cec5SDimitry Andric     }
1330b57cec5SDimitry Andric     return ParsedType();
1340b57cec5SDimitry Andric   }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric   QualType T = Context.getTypeDeclType(InjectedClassName);
1370b57cec5SDimitry Andric   DiagnoseUseOfDecl(InjectedClassName, NameLoc);
1380b57cec5SDimitry Andric   MarkAnyDeclReferenced(NameLoc, InjectedClassName, /*OdrUse=*/false);
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   return ParsedType::make(T);
1410b57cec5SDimitry Andric }
1420b57cec5SDimitry Andric 
getDestructorName(IdentifierInfo & II,SourceLocation NameLoc,Scope * S,CXXScopeSpec & SS,ParsedType ObjectTypePtr,bool EnteringContext)1435f757f3fSDimitry Andric ParsedType Sema::getDestructorName(IdentifierInfo &II, SourceLocation NameLoc,
1440b57cec5SDimitry Andric                                    Scope *S, CXXScopeSpec &SS,
1450b57cec5SDimitry Andric                                    ParsedType ObjectTypePtr,
1460b57cec5SDimitry Andric                                    bool EnteringContext) {
1470b57cec5SDimitry Andric   // Determine where to perform name lookup.
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   // FIXME: This area of the standard is very messy, and the current
1500b57cec5SDimitry Andric   // wording is rather unclear about which scopes we search for the
1510b57cec5SDimitry Andric   // destructor name; see core issues 399 and 555. Issue 399 in
1520b57cec5SDimitry Andric   // particular shows where the current description of destructor name
1530b57cec5SDimitry Andric   // lookup is completely out of line with existing practice, e.g.,
1540b57cec5SDimitry Andric   // this appears to be ill-formed:
1550b57cec5SDimitry Andric   //
1560b57cec5SDimitry Andric   //   namespace N {
1570b57cec5SDimitry Andric   //     template <typename T> struct S {
1580b57cec5SDimitry Andric   //       ~S();
1590b57cec5SDimitry Andric   //     };
1600b57cec5SDimitry Andric   //   }
1610b57cec5SDimitry Andric   //
1620b57cec5SDimitry Andric   //   void f(N::S<int>* s) {
1630b57cec5SDimitry Andric   //     s->N::S<int>::~S();
1640b57cec5SDimitry Andric   //   }
1650b57cec5SDimitry Andric   //
1660b57cec5SDimitry Andric   // See also PR6358 and PR6359.
1675ffd83dbSDimitry Andric   //
1685ffd83dbSDimitry Andric   // For now, we accept all the cases in which the name given could plausibly
1695ffd83dbSDimitry Andric   // be interpreted as a correct destructor name, issuing off-by-default
1705ffd83dbSDimitry Andric   // extension diagnostics on the cases that don't strictly conform to the
1715ffd83dbSDimitry Andric   // C++20 rules. This basically means we always consider looking in the
1725ffd83dbSDimitry Andric   // nested-name-specifier prefix, the complete nested-name-specifier, and
1735ffd83dbSDimitry Andric   // the scope, and accept if we find the expected type in any of the three
1745ffd83dbSDimitry Andric   // places.
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   if (SS.isInvalid())
1770b57cec5SDimitry Andric     return nullptr;
1780b57cec5SDimitry Andric 
1795ffd83dbSDimitry Andric   // Whether we've failed with a diagnostic already.
1805ffd83dbSDimitry Andric   bool Failed = false;
1815ffd83dbSDimitry Andric 
1825ffd83dbSDimitry Andric   llvm::SmallVector<NamedDecl*, 8> FoundDecls;
183e8d8bef9SDimitry Andric   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 8> FoundDeclSet;
1845ffd83dbSDimitry Andric 
1850b57cec5SDimitry Andric   // If we have an object type, it's because we are in a
1860b57cec5SDimitry Andric   // pseudo-destructor-expression or a member access expression, and
1870b57cec5SDimitry Andric   // we know what type we're looking for.
1885ffd83dbSDimitry Andric   QualType SearchType =
1895ffd83dbSDimitry Andric       ObjectTypePtr ? GetTypeFromParser(ObjectTypePtr) : QualType();
1900b57cec5SDimitry Andric 
1915ffd83dbSDimitry Andric   auto CheckLookupResult = [&](LookupResult &Found) -> ParsedType {
1925ffd83dbSDimitry Andric     auto IsAcceptableResult = [&](NamedDecl *D) -> bool {
1935ffd83dbSDimitry Andric       auto *Type = dyn_cast<TypeDecl>(D->getUnderlyingDecl());
1945ffd83dbSDimitry Andric       if (!Type)
1955ffd83dbSDimitry Andric         return false;
1960b57cec5SDimitry Andric 
1975ffd83dbSDimitry Andric       if (SearchType.isNull() || SearchType->isDependentType())
1985ffd83dbSDimitry Andric         return true;
1995ffd83dbSDimitry Andric 
2005ffd83dbSDimitry Andric       QualType T = Context.getTypeDeclType(Type);
2015ffd83dbSDimitry Andric       return Context.hasSameUnqualifiedType(T, SearchType);
2025ffd83dbSDimitry Andric     };
2035ffd83dbSDimitry Andric 
2045ffd83dbSDimitry Andric     unsigned NumAcceptableResults = 0;
2055ffd83dbSDimitry Andric     for (NamedDecl *D : Found) {
2065ffd83dbSDimitry Andric       if (IsAcceptableResult(D))
2075ffd83dbSDimitry Andric         ++NumAcceptableResults;
2085ffd83dbSDimitry Andric 
2095ffd83dbSDimitry Andric       // Don't list a class twice in the lookup failure diagnostic if it's
2105ffd83dbSDimitry Andric       // found by both its injected-class-name and by the name in the enclosing
2115ffd83dbSDimitry Andric       // scope.
2125ffd83dbSDimitry Andric       if (auto *RD = dyn_cast<CXXRecordDecl>(D))
2135ffd83dbSDimitry Andric         if (RD->isInjectedClassName())
2145ffd83dbSDimitry Andric           D = cast<NamedDecl>(RD->getParent());
2155ffd83dbSDimitry Andric 
2165ffd83dbSDimitry Andric       if (FoundDeclSet.insert(D).second)
2175ffd83dbSDimitry Andric         FoundDecls.push_back(D);
2180b57cec5SDimitry Andric     }
2190b57cec5SDimitry Andric 
2205ffd83dbSDimitry Andric     // As an extension, attempt to "fix" an ambiguity by erasing all non-type
2215ffd83dbSDimitry Andric     // results, and all non-matching results if we have a search type. It's not
2225ffd83dbSDimitry Andric     // clear what the right behavior is if destructor lookup hits an ambiguity,
2235ffd83dbSDimitry Andric     // but other compilers do generally accept at least some kinds of
2245ffd83dbSDimitry Andric     // ambiguity.
2255ffd83dbSDimitry Andric     if (Found.isAmbiguous() && NumAcceptableResults == 1) {
2265ffd83dbSDimitry Andric       Diag(NameLoc, diag::ext_dtor_name_ambiguous);
2275ffd83dbSDimitry Andric       LookupResult::Filter F = Found.makeFilter();
2285ffd83dbSDimitry Andric       while (F.hasNext()) {
2295ffd83dbSDimitry Andric         NamedDecl *D = F.next();
2305ffd83dbSDimitry Andric         if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
2315ffd83dbSDimitry Andric           Diag(D->getLocation(), diag::note_destructor_type_here)
2325ffd83dbSDimitry Andric               << Context.getTypeDeclType(TD);
2335ffd83dbSDimitry Andric         else
2345ffd83dbSDimitry Andric           Diag(D->getLocation(), diag::note_destructor_nontype_here);
2355ffd83dbSDimitry Andric 
2365ffd83dbSDimitry Andric         if (!IsAcceptableResult(D))
2375ffd83dbSDimitry Andric           F.erase();
2380b57cec5SDimitry Andric       }
2395ffd83dbSDimitry Andric       F.done();
2405ffd83dbSDimitry Andric     }
2415ffd83dbSDimitry Andric 
2425ffd83dbSDimitry Andric     if (Found.isAmbiguous())
2435ffd83dbSDimitry Andric       Failed = true;
2445ffd83dbSDimitry Andric 
2455ffd83dbSDimitry Andric     if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
2465ffd83dbSDimitry Andric       if (IsAcceptableResult(Type)) {
2475ffd83dbSDimitry Andric         QualType T = Context.getTypeDeclType(Type);
2485ffd83dbSDimitry Andric         MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);
2495f757f3fSDimitry Andric         return CreateParsedType(
2505f757f3fSDimitry Andric             Context.getElaboratedType(ElaboratedTypeKeyword::None, nullptr, T),
2515ffd83dbSDimitry Andric             Context.getTrivialTypeSourceInfo(T, NameLoc));
2525ffd83dbSDimitry Andric       }
2535ffd83dbSDimitry Andric     }
2545ffd83dbSDimitry Andric 
2555ffd83dbSDimitry Andric     return nullptr;
2565ffd83dbSDimitry Andric   };
2575ffd83dbSDimitry Andric 
2585ffd83dbSDimitry Andric   bool IsDependent = false;
2595ffd83dbSDimitry Andric 
2605ffd83dbSDimitry Andric   auto LookupInObjectType = [&]() -> ParsedType {
2615ffd83dbSDimitry Andric     if (Failed || SearchType.isNull())
2625ffd83dbSDimitry Andric       return nullptr;
2635ffd83dbSDimitry Andric 
2645ffd83dbSDimitry Andric     IsDependent |= SearchType->isDependentType();
2655ffd83dbSDimitry Andric 
2665ffd83dbSDimitry Andric     LookupResult Found(*this, &II, NameLoc, LookupDestructorName);
2675ffd83dbSDimitry Andric     DeclContext *LookupCtx = computeDeclContext(SearchType);
2685ffd83dbSDimitry Andric     if (!LookupCtx)
2695ffd83dbSDimitry Andric       return nullptr;
2705ffd83dbSDimitry Andric     LookupQualifiedName(Found, LookupCtx);
2715ffd83dbSDimitry Andric     return CheckLookupResult(Found);
2725ffd83dbSDimitry Andric   };
2735ffd83dbSDimitry Andric 
2745ffd83dbSDimitry Andric   auto LookupInNestedNameSpec = [&](CXXScopeSpec &LookupSS) -> ParsedType {
2755ffd83dbSDimitry Andric     if (Failed)
2765ffd83dbSDimitry Andric       return nullptr;
2775ffd83dbSDimitry Andric 
2785ffd83dbSDimitry Andric     IsDependent |= isDependentScopeSpecifier(LookupSS);
2795ffd83dbSDimitry Andric     DeclContext *LookupCtx = computeDeclContext(LookupSS, EnteringContext);
2805ffd83dbSDimitry Andric     if (!LookupCtx)
2815ffd83dbSDimitry Andric       return nullptr;
2825ffd83dbSDimitry Andric 
2835ffd83dbSDimitry Andric     LookupResult Found(*this, &II, NameLoc, LookupDestructorName);
2845ffd83dbSDimitry Andric     if (RequireCompleteDeclContext(LookupSS, LookupCtx)) {
2855ffd83dbSDimitry Andric       Failed = true;
2865ffd83dbSDimitry Andric       return nullptr;
2875ffd83dbSDimitry Andric     }
2885ffd83dbSDimitry Andric     LookupQualifiedName(Found, LookupCtx);
2895ffd83dbSDimitry Andric     return CheckLookupResult(Found);
2905ffd83dbSDimitry Andric   };
2915ffd83dbSDimitry Andric 
2925ffd83dbSDimitry Andric   auto LookupInScope = [&]() -> ParsedType {
2935ffd83dbSDimitry Andric     if (Failed || !S)
2945ffd83dbSDimitry Andric       return nullptr;
2955ffd83dbSDimitry Andric 
2965ffd83dbSDimitry Andric     LookupResult Found(*this, &II, NameLoc, LookupDestructorName);
2975ffd83dbSDimitry Andric     LookupName(Found, S);
2985ffd83dbSDimitry Andric     return CheckLookupResult(Found);
2995ffd83dbSDimitry Andric   };
3005ffd83dbSDimitry Andric 
3015ffd83dbSDimitry Andric   // C++2a [basic.lookup.qual]p6:
3025ffd83dbSDimitry Andric   //   In a qualified-id of the form
3035ffd83dbSDimitry Andric   //
3045ffd83dbSDimitry Andric   //     nested-name-specifier[opt] type-name :: ~ type-name
3055ffd83dbSDimitry Andric   //
3065ffd83dbSDimitry Andric   //   the second type-name is looked up in the same scope as the first.
3075ffd83dbSDimitry Andric   //
3085ffd83dbSDimitry Andric   // We interpret this as meaning that if you do a dual-scope lookup for the
3095ffd83dbSDimitry Andric   // first name, you also do a dual-scope lookup for the second name, per
3105ffd83dbSDimitry Andric   // C++ [basic.lookup.classref]p4:
3115ffd83dbSDimitry Andric   //
3125ffd83dbSDimitry Andric   //   If the id-expression in a class member access is a qualified-id of the
3135ffd83dbSDimitry Andric   //   form
3145ffd83dbSDimitry Andric   //
3155ffd83dbSDimitry Andric   //     class-name-or-namespace-name :: ...
3165ffd83dbSDimitry Andric   //
3175ffd83dbSDimitry Andric   //   the class-name-or-namespace-name following the . or -> is first looked
3185ffd83dbSDimitry Andric   //   up in the class of the object expression and the name, if found, is used.
3195ffd83dbSDimitry Andric   //   Otherwise, it is looked up in the context of the entire
3205ffd83dbSDimitry Andric   //   postfix-expression.
3215ffd83dbSDimitry Andric   //
3225ffd83dbSDimitry Andric   // This looks in the same scopes as for an unqualified destructor name:
3235ffd83dbSDimitry Andric   //
3240b57cec5SDimitry Andric   // C++ [basic.lookup.classref]p3:
3250b57cec5SDimitry Andric   //   If the unqualified-id is ~ type-name, the type-name is looked up
3260b57cec5SDimitry Andric   //   in the context of the entire postfix-expression. If the type T
3270b57cec5SDimitry Andric   //   of the object expression is of a class type C, the type-name is
3280b57cec5SDimitry Andric   //   also looked up in the scope of class C. At least one of the
3295ffd83dbSDimitry Andric   //   lookups shall find a name that refers to cv T.
3305ffd83dbSDimitry Andric   //
3315ffd83dbSDimitry Andric   // FIXME: The intent is unclear here. Should type-name::~type-name look in
3325ffd83dbSDimitry Andric   // the scope anyway if it finds a non-matching name declared in the class?
3335ffd83dbSDimitry Andric   // If both lookups succeed and find a dependent result, which result should
3345ffd83dbSDimitry Andric   // we retain? (Same question for p->~type-name().)
3350b57cec5SDimitry Andric 
3365ffd83dbSDimitry Andric   if (NestedNameSpecifier *Prefix =
3375ffd83dbSDimitry Andric       SS.isSet() ? SS.getScopeRep()->getPrefix() : nullptr) {
3385ffd83dbSDimitry Andric     // This is
3395ffd83dbSDimitry Andric     //
3405ffd83dbSDimitry Andric     //   nested-name-specifier type-name :: ~ type-name
3415ffd83dbSDimitry Andric     //
3425ffd83dbSDimitry Andric     // Look for the second type-name in the nested-name-specifier.
3435ffd83dbSDimitry Andric     CXXScopeSpec PrefixSS;
3445ffd83dbSDimitry Andric     PrefixSS.Adopt(NestedNameSpecifierLoc(Prefix, SS.location_data()));
3455ffd83dbSDimitry Andric     if (ParsedType T = LookupInNestedNameSpec(PrefixSS))
3465ffd83dbSDimitry Andric       return T;
3470b57cec5SDimitry Andric   } else {
3485ffd83dbSDimitry Andric     // This is one of
3495ffd83dbSDimitry Andric     //
3505ffd83dbSDimitry Andric     //   type-name :: ~ type-name
3515ffd83dbSDimitry Andric     //   ~ type-name
3525ffd83dbSDimitry Andric     //
3535ffd83dbSDimitry Andric     // Look in the scope and (if any) the object type.
3545ffd83dbSDimitry Andric     if (ParsedType T = LookupInScope())
3555ffd83dbSDimitry Andric       return T;
3565ffd83dbSDimitry Andric     if (ParsedType T = LookupInObjectType())
3575ffd83dbSDimitry Andric       return T;
3580b57cec5SDimitry Andric   }
3590b57cec5SDimitry Andric 
3605ffd83dbSDimitry Andric   if (Failed)
3610b57cec5SDimitry Andric     return nullptr;
3620b57cec5SDimitry Andric 
3635ffd83dbSDimitry Andric   if (IsDependent) {
3645ffd83dbSDimitry Andric     // We didn't find our type, but that's OK: it's dependent anyway.
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric     // FIXME: What if we have no nested-name-specifier?
3675f757f3fSDimitry Andric     QualType T =
3685f757f3fSDimitry Andric         CheckTypenameType(ElaboratedTypeKeyword::None, SourceLocation(),
3695f757f3fSDimitry Andric                           SS.getWithLocInContext(Context), II, NameLoc);
3700b57cec5SDimitry Andric     return ParsedType::make(T);
3710b57cec5SDimitry Andric   }
3720b57cec5SDimitry Andric 
3735ffd83dbSDimitry Andric   // The remaining cases are all non-standard extensions imitating the behavior
3745ffd83dbSDimitry Andric   // of various other compilers.
3755ffd83dbSDimitry Andric   unsigned NumNonExtensionDecls = FoundDecls.size();
3765ffd83dbSDimitry Andric 
3775ffd83dbSDimitry Andric   if (SS.isSet()) {
3785ffd83dbSDimitry Andric     // For compatibility with older broken C++ rules and existing code,
3795ffd83dbSDimitry Andric     //
3805ffd83dbSDimitry Andric     //   nested-name-specifier :: ~ type-name
3815ffd83dbSDimitry Andric     //
3825ffd83dbSDimitry Andric     // also looks for type-name within the nested-name-specifier.
3835ffd83dbSDimitry Andric     if (ParsedType T = LookupInNestedNameSpec(SS)) {
3845ffd83dbSDimitry Andric       Diag(SS.getEndLoc(), diag::ext_dtor_named_in_wrong_scope)
3855ffd83dbSDimitry Andric           << SS.getRange()
3865ffd83dbSDimitry Andric           << FixItHint::CreateInsertion(SS.getEndLoc(),
3875ffd83dbSDimitry Andric                                         ("::" + II.getName()).str());
3885ffd83dbSDimitry Andric       return T;
3890b57cec5SDimitry Andric     }
3905ffd83dbSDimitry Andric 
3915ffd83dbSDimitry Andric     // For compatibility with other compilers and older versions of Clang,
3925ffd83dbSDimitry Andric     //
3935ffd83dbSDimitry Andric     //   nested-name-specifier type-name :: ~ type-name
3945ffd83dbSDimitry Andric     //
3955ffd83dbSDimitry Andric     // also looks for type-name in the scope. Unfortunately, we can't
3965ffd83dbSDimitry Andric     // reasonably apply this fallback for dependent nested-name-specifiers.
39706c3fb27SDimitry Andric     if (SS.isValid() && SS.getScopeRep()->getPrefix()) {
3985ffd83dbSDimitry Andric       if (ParsedType T = LookupInScope()) {
3995ffd83dbSDimitry Andric         Diag(SS.getEndLoc(), diag::ext_qualified_dtor_named_in_lexical_scope)
4005ffd83dbSDimitry Andric             << FixItHint::CreateRemoval(SS.getRange());
4015ffd83dbSDimitry Andric         Diag(FoundDecls.back()->getLocation(), diag::note_destructor_type_here)
4025ffd83dbSDimitry Andric             << GetTypeFromParser(T);
4035ffd83dbSDimitry Andric         return T;
4045ffd83dbSDimitry Andric       }
4055ffd83dbSDimitry Andric     }
4065ffd83dbSDimitry Andric   }
4075ffd83dbSDimitry Andric 
4085ffd83dbSDimitry Andric   // We didn't find anything matching; tell the user what we did find (if
4095ffd83dbSDimitry Andric   // anything).
4105ffd83dbSDimitry Andric 
4115ffd83dbSDimitry Andric   // Don't tell the user about declarations we shouldn't have found.
4125ffd83dbSDimitry Andric   FoundDecls.resize(NumNonExtensionDecls);
4135ffd83dbSDimitry Andric 
4145ffd83dbSDimitry Andric   // List types before non-types.
4155ffd83dbSDimitry Andric   std::stable_sort(FoundDecls.begin(), FoundDecls.end(),
4165ffd83dbSDimitry Andric                    [](NamedDecl *A, NamedDecl *B) {
4175ffd83dbSDimitry Andric                      return isa<TypeDecl>(A->getUnderlyingDecl()) >
4185ffd83dbSDimitry Andric                             isa<TypeDecl>(B->getUnderlyingDecl());
4195ffd83dbSDimitry Andric                    });
4205ffd83dbSDimitry Andric 
4215ffd83dbSDimitry Andric   // Suggest a fixit to properly name the destroyed type.
4225ffd83dbSDimitry Andric   auto MakeFixItHint = [&]{
4235ffd83dbSDimitry Andric     const CXXRecordDecl *Destroyed = nullptr;
4245ffd83dbSDimitry Andric     // FIXME: If we have a scope specifier, suggest its last component?
4255ffd83dbSDimitry Andric     if (!SearchType.isNull())
4265ffd83dbSDimitry Andric       Destroyed = SearchType->getAsCXXRecordDecl();
4275ffd83dbSDimitry Andric     else if (S)
4285ffd83dbSDimitry Andric       Destroyed = dyn_cast_or_null<CXXRecordDecl>(S->getEntity());
4295ffd83dbSDimitry Andric     if (Destroyed)
4305ffd83dbSDimitry Andric       return FixItHint::CreateReplacement(SourceRange(NameLoc),
4315ffd83dbSDimitry Andric                                           Destroyed->getNameAsString());
4325ffd83dbSDimitry Andric     return FixItHint();
4335ffd83dbSDimitry Andric   };
4345ffd83dbSDimitry Andric 
4355ffd83dbSDimitry Andric   if (FoundDecls.empty()) {
4365ffd83dbSDimitry Andric     // FIXME: Attempt typo-correction?
4375ffd83dbSDimitry Andric     Diag(NameLoc, diag::err_undeclared_destructor_name)
4385ffd83dbSDimitry Andric       << &II << MakeFixItHint();
4395ffd83dbSDimitry Andric   } else if (!SearchType.isNull() && FoundDecls.size() == 1) {
4405ffd83dbSDimitry Andric     if (auto *TD = dyn_cast<TypeDecl>(FoundDecls[0]->getUnderlyingDecl())) {
4415ffd83dbSDimitry Andric       assert(!SearchType.isNull() &&
4425ffd83dbSDimitry Andric              "should only reject a type result if we have a search type");
4435ffd83dbSDimitry Andric       QualType T = Context.getTypeDeclType(TD);
4445ffd83dbSDimitry Andric       Diag(NameLoc, diag::err_destructor_expr_type_mismatch)
4455ffd83dbSDimitry Andric           << T << SearchType << MakeFixItHint();
4465ffd83dbSDimitry Andric     } else {
4475ffd83dbSDimitry Andric       Diag(NameLoc, diag::err_destructor_expr_nontype)
4485ffd83dbSDimitry Andric           << &II << MakeFixItHint();
4495ffd83dbSDimitry Andric     }
4505ffd83dbSDimitry Andric   } else {
4515ffd83dbSDimitry Andric     Diag(NameLoc, SearchType.isNull() ? diag::err_destructor_name_nontype
4525ffd83dbSDimitry Andric                                       : diag::err_destructor_expr_mismatch)
4535ffd83dbSDimitry Andric         << &II << SearchType << MakeFixItHint();
4545ffd83dbSDimitry Andric   }
4555ffd83dbSDimitry Andric 
4565ffd83dbSDimitry Andric   for (NamedDecl *FoundD : FoundDecls) {
4575ffd83dbSDimitry Andric     if (auto *TD = dyn_cast<TypeDecl>(FoundD->getUnderlyingDecl()))
4585ffd83dbSDimitry Andric       Diag(FoundD->getLocation(), diag::note_destructor_type_here)
4595ffd83dbSDimitry Andric           << Context.getTypeDeclType(TD);
4605ffd83dbSDimitry Andric     else
4615ffd83dbSDimitry Andric       Diag(FoundD->getLocation(), diag::note_destructor_nontype_here)
4625ffd83dbSDimitry Andric           << FoundD;
4630b57cec5SDimitry Andric   }
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   return nullptr;
4660b57cec5SDimitry Andric }
4670b57cec5SDimitry Andric 
getDestructorTypeForDecltype(const DeclSpec & DS,ParsedType ObjectType)4680b57cec5SDimitry Andric ParsedType Sema::getDestructorTypeForDecltype(const DeclSpec &DS,
4690b57cec5SDimitry Andric                                               ParsedType ObjectType) {
4700b57cec5SDimitry Andric   if (DS.getTypeSpecType() == DeclSpec::TST_error)
4710b57cec5SDimitry Andric     return nullptr;
4720b57cec5SDimitry Andric 
4730b57cec5SDimitry Andric   if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto) {
4740b57cec5SDimitry Andric     Diag(DS.getTypeSpecTypeLoc(), diag::err_decltype_auto_invalid);
4750b57cec5SDimitry Andric     return nullptr;
4760b57cec5SDimitry Andric   }
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric   assert(DS.getTypeSpecType() == DeclSpec::TST_decltype &&
4790b57cec5SDimitry Andric          "unexpected type in getDestructorType");
480349cc55cSDimitry Andric   QualType T = BuildDecltypeType(DS.getRepAsExpr());
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric   // If we know the type of the object, check that the correct destructor
4830b57cec5SDimitry Andric   // type was named now; we can give better diagnostics this way.
4840b57cec5SDimitry Andric   QualType SearchType = GetTypeFromParser(ObjectType);
4850b57cec5SDimitry Andric   if (!SearchType.isNull() && !SearchType->isDependentType() &&
4860b57cec5SDimitry Andric       !Context.hasSameUnqualifiedType(T, SearchType)) {
4870b57cec5SDimitry Andric     Diag(DS.getTypeSpecTypeLoc(), diag::err_destructor_expr_type_mismatch)
4880b57cec5SDimitry Andric       << T << SearchType;
4890b57cec5SDimitry Andric     return nullptr;
4900b57cec5SDimitry Andric   }
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric   return ParsedType::make(T);
4930b57cec5SDimitry Andric }
4940b57cec5SDimitry Andric 
checkLiteralOperatorId(const CXXScopeSpec & SS,const UnqualifiedId & Name,bool IsUDSuffix)4950b57cec5SDimitry Andric bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
496fe6060f1SDimitry Andric                                   const UnqualifiedId &Name, bool IsUDSuffix) {
4970b57cec5SDimitry Andric   assert(Name.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId);
498fe6060f1SDimitry Andric   if (!IsUDSuffix) {
499fe6060f1SDimitry Andric     // [over.literal] p8
500fe6060f1SDimitry Andric     //
501fe6060f1SDimitry Andric     // double operator""_Bq(long double);  // OK: not a reserved identifier
502fe6060f1SDimitry Andric     // double operator"" _Bq(long double); // ill-formed, no diagnostic required
503fe6060f1SDimitry Andric     IdentifierInfo *II = Name.Identifier;
504fe6060f1SDimitry Andric     ReservedIdentifierStatus Status = II->isReserved(PP.getLangOpts());
505fe6060f1SDimitry Andric     SourceLocation Loc = Name.getEndLoc();
50606c3fb27SDimitry Andric     if (!PP.getSourceManager().isInSystemHeader(Loc)) {
50706c3fb27SDimitry Andric       if (auto Hint = FixItHint::CreateReplacement(
508fe6060f1SDimitry Andric               Name.getSourceRange(),
509fe6060f1SDimitry Andric               (StringRef("operator\"\"") + II->getName()).str());
51006c3fb27SDimitry Andric           isReservedInAllContexts(Status)) {
51106c3fb27SDimitry Andric         Diag(Loc, diag::warn_reserved_extern_symbol)
51206c3fb27SDimitry Andric             << II << static_cast<int>(Status) << Hint;
51306c3fb27SDimitry Andric       } else {
51406c3fb27SDimitry Andric         Diag(Loc, diag::warn_deprecated_literal_operator_id) << II << Hint;
51506c3fb27SDimitry Andric       }
516fe6060f1SDimitry Andric     }
517fe6060f1SDimitry Andric   }
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric   if (!SS.isValid())
5200b57cec5SDimitry Andric     return false;
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric   switch (SS.getScopeRep()->getKind()) {
5230b57cec5SDimitry Andric   case NestedNameSpecifier::Identifier:
5240b57cec5SDimitry Andric   case NestedNameSpecifier::TypeSpec:
5250b57cec5SDimitry Andric   case NestedNameSpecifier::TypeSpecWithTemplate:
5260b57cec5SDimitry Andric     // Per C++11 [over.literal]p2, literal operators can only be declared at
5270b57cec5SDimitry Andric     // namespace scope. Therefore, this unqualified-id cannot name anything.
5280b57cec5SDimitry Andric     // Reject it early, because we have no AST representation for this in the
5290b57cec5SDimitry Andric     // case where the scope is dependent.
5300b57cec5SDimitry Andric     Diag(Name.getBeginLoc(), diag::err_literal_operator_id_outside_namespace)
5310b57cec5SDimitry Andric         << SS.getScopeRep();
5320b57cec5SDimitry Andric     return true;
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric   case NestedNameSpecifier::Global:
5350b57cec5SDimitry Andric   case NestedNameSpecifier::Super:
5360b57cec5SDimitry Andric   case NestedNameSpecifier::Namespace:
5370b57cec5SDimitry Andric   case NestedNameSpecifier::NamespaceAlias:
5380b57cec5SDimitry Andric     return false;
5390b57cec5SDimitry Andric   }
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric   llvm_unreachable("unknown nested name specifier kind");
5420b57cec5SDimitry Andric }
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric /// Build a C++ typeid expression with a type operand.
BuildCXXTypeId(QualType TypeInfoType,SourceLocation TypeidLoc,TypeSourceInfo * Operand,SourceLocation RParenLoc)5450b57cec5SDimitry Andric ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
5460b57cec5SDimitry Andric                                 SourceLocation TypeidLoc,
5470b57cec5SDimitry Andric                                 TypeSourceInfo *Operand,
5480b57cec5SDimitry Andric                                 SourceLocation RParenLoc) {
5490b57cec5SDimitry Andric   // C++ [expr.typeid]p4:
5500b57cec5SDimitry Andric   //   The top-level cv-qualifiers of the lvalue expression or the type-id
5510b57cec5SDimitry Andric   //   that is the operand of typeid are always ignored.
5520b57cec5SDimitry Andric   //   If the type of the type-id is a class type or a reference to a class
5530b57cec5SDimitry Andric   //   type, the class shall be completely-defined.
5540b57cec5SDimitry Andric   Qualifiers Quals;
5550b57cec5SDimitry Andric   QualType T
5560b57cec5SDimitry Andric     = Context.getUnqualifiedArrayType(Operand->getType().getNonReferenceType(),
5570b57cec5SDimitry Andric                                       Quals);
5580b57cec5SDimitry Andric   if (T->getAs<RecordType>() &&
5590b57cec5SDimitry Andric       RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
5600b57cec5SDimitry Andric     return ExprError();
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric   if (T->isVariablyModifiedType())
5630b57cec5SDimitry Andric     return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << T);
5640b57cec5SDimitry Andric 
565a7dea167SDimitry Andric   if (CheckQualifiedFunctionForTypeId(T, TypeidLoc))
566a7dea167SDimitry Andric     return ExprError();
567a7dea167SDimitry Andric 
5680b57cec5SDimitry Andric   return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand,
5690b57cec5SDimitry Andric                                      SourceRange(TypeidLoc, RParenLoc));
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric /// Build a C++ typeid expression with an expression operand.
BuildCXXTypeId(QualType TypeInfoType,SourceLocation TypeidLoc,Expr * E,SourceLocation RParenLoc)5730b57cec5SDimitry Andric ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
5740b57cec5SDimitry Andric                                 SourceLocation TypeidLoc,
5750b57cec5SDimitry Andric                                 Expr *E,
5760b57cec5SDimitry Andric                                 SourceLocation RParenLoc) {
5770b57cec5SDimitry Andric   bool WasEvaluated = false;
5780b57cec5SDimitry Andric   if (E && !E->isTypeDependent()) {
5791fd87a68SDimitry Andric     if (E->hasPlaceholderType()) {
5800b57cec5SDimitry Andric       ExprResult result = CheckPlaceholderExpr(E);
5810b57cec5SDimitry Andric       if (result.isInvalid()) return ExprError();
5820b57cec5SDimitry Andric       E = result.get();
5830b57cec5SDimitry Andric     }
5840b57cec5SDimitry Andric 
5850b57cec5SDimitry Andric     QualType T = E->getType();
5860b57cec5SDimitry Andric     if (const RecordType *RecordT = T->getAs<RecordType>()) {
5870b57cec5SDimitry Andric       CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl());
5880b57cec5SDimitry Andric       // C++ [expr.typeid]p3:
5890b57cec5SDimitry Andric       //   [...] If the type of the expression is a class type, the class
5900b57cec5SDimitry Andric       //   shall be completely-defined.
5910b57cec5SDimitry Andric       if (RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
5920b57cec5SDimitry Andric         return ExprError();
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric       // C++ [expr.typeid]p3:
5950b57cec5SDimitry Andric       //   When typeid is applied to an expression other than an glvalue of a
5960b57cec5SDimitry Andric       //   polymorphic class type [...] [the] expression is an unevaluated
5970b57cec5SDimitry Andric       //   operand. [...]
5980b57cec5SDimitry Andric       if (RecordD->isPolymorphic() && E->isGLValue()) {
599fe6060f1SDimitry Andric         if (isUnevaluatedContext()) {
600fe6060f1SDimitry Andric           // The operand was processed in unevaluated context, switch the
601fe6060f1SDimitry Andric           // context and recheck the subexpression.
6020b57cec5SDimitry Andric           ExprResult Result = TransformToPotentiallyEvaluated(E);
603fe6060f1SDimitry Andric           if (Result.isInvalid())
604fe6060f1SDimitry Andric             return ExprError();
6050b57cec5SDimitry Andric           E = Result.get();
606fe6060f1SDimitry Andric         }
6070b57cec5SDimitry Andric 
6080b57cec5SDimitry Andric         // We require a vtable to query the type at run time.
6090b57cec5SDimitry Andric         MarkVTableUsed(TypeidLoc, RecordD);
6100b57cec5SDimitry Andric         WasEvaluated = true;
6110b57cec5SDimitry Andric       }
6120b57cec5SDimitry Andric     }
6130b57cec5SDimitry Andric 
614a7dea167SDimitry Andric     ExprResult Result = CheckUnevaluatedOperand(E);
615a7dea167SDimitry Andric     if (Result.isInvalid())
616a7dea167SDimitry Andric       return ExprError();
617a7dea167SDimitry Andric     E = Result.get();
618a7dea167SDimitry Andric 
6190b57cec5SDimitry Andric     // C++ [expr.typeid]p4:
6200b57cec5SDimitry Andric     //   [...] If the type of the type-id is a reference to a possibly
6210b57cec5SDimitry Andric     //   cv-qualified type, the result of the typeid expression refers to a
6220b57cec5SDimitry Andric     //   std::type_info object representing the cv-unqualified referenced
6230b57cec5SDimitry Andric     //   type.
6240b57cec5SDimitry Andric     Qualifiers Quals;
6250b57cec5SDimitry Andric     QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
6260b57cec5SDimitry Andric     if (!Context.hasSameType(T, UnqualT)) {
6270b57cec5SDimitry Andric       T = UnqualT;
6280b57cec5SDimitry Andric       E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).get();
6290b57cec5SDimitry Andric     }
6300b57cec5SDimitry Andric   }
6310b57cec5SDimitry Andric 
6320b57cec5SDimitry Andric   if (E->getType()->isVariablyModifiedType())
6330b57cec5SDimitry Andric     return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid)
6340b57cec5SDimitry Andric                      << E->getType());
6350b57cec5SDimitry Andric   else if (!inTemplateInstantiation() &&
6360b57cec5SDimitry Andric            E->HasSideEffects(Context, WasEvaluated)) {
6370b57cec5SDimitry Andric     // The expression operand for typeid is in an unevaluated expression
6380b57cec5SDimitry Andric     // context, so side effects could result in unintended consequences.
6390b57cec5SDimitry Andric     Diag(E->getExprLoc(), WasEvaluated
6400b57cec5SDimitry Andric                               ? diag::warn_side_effects_typeid
6410b57cec5SDimitry Andric                               : diag::warn_side_effects_unevaluated_context);
6420b57cec5SDimitry Andric   }
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E,
6450b57cec5SDimitry Andric                                      SourceRange(TypeidLoc, RParenLoc));
6460b57cec5SDimitry Andric }
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric /// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
6490b57cec5SDimitry Andric ExprResult
ActOnCXXTypeid(SourceLocation OpLoc,SourceLocation LParenLoc,bool isType,void * TyOrExpr,SourceLocation RParenLoc)6500b57cec5SDimitry Andric Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
6510b57cec5SDimitry Andric                      bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
6520b57cec5SDimitry Andric   // typeid is not supported in OpenCL.
6530b57cec5SDimitry Andric   if (getLangOpts().OpenCLCPlusPlus) {
6540b57cec5SDimitry Andric     return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported)
6550b57cec5SDimitry Andric                      << "typeid");
6560b57cec5SDimitry Andric   }
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric   // Find the std::type_info type.
6590b57cec5SDimitry Andric   if (!getStdNamespace())
6600b57cec5SDimitry Andric     return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric   if (!CXXTypeInfoDecl) {
6630b57cec5SDimitry Andric     IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
6640b57cec5SDimitry Andric     LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
6650b57cec5SDimitry Andric     LookupQualifiedName(R, getStdNamespace());
6660b57cec5SDimitry Andric     CXXTypeInfoDecl = R.getAsSingle<RecordDecl>();
6670b57cec5SDimitry Andric     // Microsoft's typeinfo doesn't have type_info in std but in the global
6680b57cec5SDimitry Andric     // namespace if _HAS_EXCEPTIONS is defined to 0. See PR13153.
6690b57cec5SDimitry Andric     if (!CXXTypeInfoDecl && LangOpts.MSVCCompat) {
6700b57cec5SDimitry Andric       LookupQualifiedName(R, Context.getTranslationUnitDecl());
6710b57cec5SDimitry Andric       CXXTypeInfoDecl = R.getAsSingle<RecordDecl>();
6720b57cec5SDimitry Andric     }
6730b57cec5SDimitry Andric     if (!CXXTypeInfoDecl)
6740b57cec5SDimitry Andric       return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
6750b57cec5SDimitry Andric   }
6760b57cec5SDimitry Andric 
6770b57cec5SDimitry Andric   if (!getLangOpts().RTTI) {
6780b57cec5SDimitry Andric     return ExprError(Diag(OpLoc, diag::err_no_typeid_with_fno_rtti));
6790b57cec5SDimitry Andric   }
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric   QualType TypeInfoType = Context.getTypeDeclType(CXXTypeInfoDecl);
6820b57cec5SDimitry Andric 
6830b57cec5SDimitry Andric   if (isType) {
6840b57cec5SDimitry Andric     // The operand is a type; handle it as such.
6850b57cec5SDimitry Andric     TypeSourceInfo *TInfo = nullptr;
6860b57cec5SDimitry Andric     QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
6870b57cec5SDimitry Andric                                    &TInfo);
6880b57cec5SDimitry Andric     if (T.isNull())
6890b57cec5SDimitry Andric       return ExprError();
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric     if (!TInfo)
6920b57cec5SDimitry Andric       TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric     return BuildCXXTypeId(TypeInfoType, OpLoc, TInfo, RParenLoc);
6950b57cec5SDimitry Andric   }
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric   // The operand is an expression.
698e8d8bef9SDimitry Andric   ExprResult Result =
699e8d8bef9SDimitry Andric       BuildCXXTypeId(TypeInfoType, OpLoc, (Expr *)TyOrExpr, RParenLoc);
700e8d8bef9SDimitry Andric 
701e8d8bef9SDimitry Andric   if (!getLangOpts().RTTIData && !Result.isInvalid())
702e8d8bef9SDimitry Andric     if (auto *CTE = dyn_cast<CXXTypeidExpr>(Result.get()))
703e8d8bef9SDimitry Andric       if (CTE->isPotentiallyEvaluated() && !CTE->isMostDerived(Context))
704e8d8bef9SDimitry Andric         Diag(OpLoc, diag::warn_no_typeid_with_rtti_disabled)
705e8d8bef9SDimitry Andric             << (getDiagnostics().getDiagnosticOptions().getFormat() ==
706e8d8bef9SDimitry Andric                 DiagnosticOptions::MSVC);
707e8d8bef9SDimitry Andric   return Result;
7080b57cec5SDimitry Andric }
7090b57cec5SDimitry Andric 
7100b57cec5SDimitry Andric /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
7110b57cec5SDimitry Andric /// a single GUID.
7120b57cec5SDimitry Andric static void
getUuidAttrOfType(Sema & SemaRef,QualType QT,llvm::SmallSetVector<const UuidAttr *,1> & UuidAttrs)7130b57cec5SDimitry Andric getUuidAttrOfType(Sema &SemaRef, QualType QT,
7140b57cec5SDimitry Andric                   llvm::SmallSetVector<const UuidAttr *, 1> &UuidAttrs) {
7150b57cec5SDimitry Andric   // Optionally remove one level of pointer, reference or array indirection.
7160b57cec5SDimitry Andric   const Type *Ty = QT.getTypePtr();
7170b57cec5SDimitry Andric   if (QT->isPointerType() || QT->isReferenceType())
7180b57cec5SDimitry Andric     Ty = QT->getPointeeType().getTypePtr();
7190b57cec5SDimitry Andric   else if (QT->isArrayType())
7200b57cec5SDimitry Andric     Ty = Ty->getBaseElementTypeUnsafe();
7210b57cec5SDimitry Andric 
7220b57cec5SDimitry Andric   const auto *TD = Ty->getAsTagDecl();
7230b57cec5SDimitry Andric   if (!TD)
7240b57cec5SDimitry Andric     return;
7250b57cec5SDimitry Andric 
7260b57cec5SDimitry Andric   if (const auto *Uuid = TD->getMostRecentDecl()->getAttr<UuidAttr>()) {
7270b57cec5SDimitry Andric     UuidAttrs.insert(Uuid);
7280b57cec5SDimitry Andric     return;
7290b57cec5SDimitry Andric   }
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric   // __uuidof can grab UUIDs from template arguments.
7320b57cec5SDimitry Andric   if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(TD)) {
7330b57cec5SDimitry Andric     const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
7340b57cec5SDimitry Andric     for (const TemplateArgument &TA : TAL.asArray()) {
7350b57cec5SDimitry Andric       const UuidAttr *UuidForTA = nullptr;
7360b57cec5SDimitry Andric       if (TA.getKind() == TemplateArgument::Type)
7370b57cec5SDimitry Andric         getUuidAttrOfType(SemaRef, TA.getAsType(), UuidAttrs);
7380b57cec5SDimitry Andric       else if (TA.getKind() == TemplateArgument::Declaration)
7390b57cec5SDimitry Andric         getUuidAttrOfType(SemaRef, TA.getAsDecl()->getType(), UuidAttrs);
7400b57cec5SDimitry Andric 
7410b57cec5SDimitry Andric       if (UuidForTA)
7420b57cec5SDimitry Andric         UuidAttrs.insert(UuidForTA);
7430b57cec5SDimitry Andric     }
7440b57cec5SDimitry Andric   }
7450b57cec5SDimitry Andric }
7460b57cec5SDimitry Andric 
7470b57cec5SDimitry Andric /// Build a Microsoft __uuidof expression with a type operand.
BuildCXXUuidof(QualType Type,SourceLocation TypeidLoc,TypeSourceInfo * Operand,SourceLocation RParenLoc)7485ffd83dbSDimitry Andric ExprResult Sema::BuildCXXUuidof(QualType Type,
7490b57cec5SDimitry Andric                                 SourceLocation TypeidLoc,
7500b57cec5SDimitry Andric                                 TypeSourceInfo *Operand,
7510b57cec5SDimitry Andric                                 SourceLocation RParenLoc) {
7525ffd83dbSDimitry Andric   MSGuidDecl *Guid = nullptr;
7530b57cec5SDimitry Andric   if (!Operand->getType()->isDependentType()) {
7540b57cec5SDimitry Andric     llvm::SmallSetVector<const UuidAttr *, 1> UuidAttrs;
7550b57cec5SDimitry Andric     getUuidAttrOfType(*this, Operand->getType(), UuidAttrs);
7560b57cec5SDimitry Andric     if (UuidAttrs.empty())
7570b57cec5SDimitry Andric       return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
7580b57cec5SDimitry Andric     if (UuidAttrs.size() > 1)
7590b57cec5SDimitry Andric       return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
7605ffd83dbSDimitry Andric     Guid = UuidAttrs.back()->getGuidDecl();
7610b57cec5SDimitry Andric   }
7620b57cec5SDimitry Andric 
7635ffd83dbSDimitry Andric   return new (Context)
7645ffd83dbSDimitry Andric       CXXUuidofExpr(Type, Operand, Guid, SourceRange(TypeidLoc, RParenLoc));
7650b57cec5SDimitry Andric }
7660b57cec5SDimitry Andric 
7670b57cec5SDimitry Andric /// Build a Microsoft __uuidof expression with an expression operand.
BuildCXXUuidof(QualType Type,SourceLocation TypeidLoc,Expr * E,SourceLocation RParenLoc)7685ffd83dbSDimitry Andric ExprResult Sema::BuildCXXUuidof(QualType Type, SourceLocation TypeidLoc,
7695ffd83dbSDimitry Andric                                 Expr *E, SourceLocation RParenLoc) {
7705ffd83dbSDimitry Andric   MSGuidDecl *Guid = nullptr;
7710b57cec5SDimitry Andric   if (!E->getType()->isDependentType()) {
7720b57cec5SDimitry Andric     if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
7735ffd83dbSDimitry Andric       // A null pointer results in {00000000-0000-0000-0000-000000000000}.
7745ffd83dbSDimitry Andric       Guid = Context.getMSGuidDecl(MSGuidDecl::Parts{});
7750b57cec5SDimitry Andric     } else {
7760b57cec5SDimitry Andric       llvm::SmallSetVector<const UuidAttr *, 1> UuidAttrs;
7770b57cec5SDimitry Andric       getUuidAttrOfType(*this, E->getType(), UuidAttrs);
7780b57cec5SDimitry Andric       if (UuidAttrs.empty())
7790b57cec5SDimitry Andric         return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
7800b57cec5SDimitry Andric       if (UuidAttrs.size() > 1)
7810b57cec5SDimitry Andric         return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
7825ffd83dbSDimitry Andric       Guid = UuidAttrs.back()->getGuidDecl();
7830b57cec5SDimitry Andric     }
7840b57cec5SDimitry Andric   }
7850b57cec5SDimitry Andric 
7865ffd83dbSDimitry Andric   return new (Context)
7875ffd83dbSDimitry Andric       CXXUuidofExpr(Type, E, Guid, SourceRange(TypeidLoc, RParenLoc));
7880b57cec5SDimitry Andric }
7890b57cec5SDimitry Andric 
7900b57cec5SDimitry Andric /// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression);
7910b57cec5SDimitry Andric ExprResult
ActOnCXXUuidof(SourceLocation OpLoc,SourceLocation LParenLoc,bool isType,void * TyOrExpr,SourceLocation RParenLoc)7920b57cec5SDimitry Andric Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc,
7930b57cec5SDimitry Andric                      bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
7945ffd83dbSDimitry Andric   QualType GuidType = Context.getMSGuidType();
7955ffd83dbSDimitry Andric   GuidType.addConst();
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric   if (isType) {
7980b57cec5SDimitry Andric     // The operand is a type; handle it as such.
7990b57cec5SDimitry Andric     TypeSourceInfo *TInfo = nullptr;
8000b57cec5SDimitry Andric     QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
8010b57cec5SDimitry Andric                                    &TInfo);
8020b57cec5SDimitry Andric     if (T.isNull())
8030b57cec5SDimitry Andric       return ExprError();
8040b57cec5SDimitry Andric 
8050b57cec5SDimitry Andric     if (!TInfo)
8060b57cec5SDimitry Andric       TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric     return BuildCXXUuidof(GuidType, OpLoc, TInfo, RParenLoc);
8090b57cec5SDimitry Andric   }
8100b57cec5SDimitry Andric 
8110b57cec5SDimitry Andric   // The operand is an expression.
8120b57cec5SDimitry Andric   return BuildCXXUuidof(GuidType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
8130b57cec5SDimitry Andric }
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric /// ActOnCXXBoolLiteral - Parse {true,false} literals.
8160b57cec5SDimitry Andric ExprResult
ActOnCXXBoolLiteral(SourceLocation OpLoc,tok::TokenKind Kind)8170b57cec5SDimitry Andric Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
8180b57cec5SDimitry Andric   assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
8190b57cec5SDimitry Andric          "Unknown C++ Boolean value!");
8200b57cec5SDimitry Andric   return new (Context)
8210b57cec5SDimitry Andric       CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
8220b57cec5SDimitry Andric }
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
8250b57cec5SDimitry Andric ExprResult
ActOnCXXNullPtrLiteral(SourceLocation Loc)8260b57cec5SDimitry Andric Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
8270b57cec5SDimitry Andric   return new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc);
8280b57cec5SDimitry Andric }
8290b57cec5SDimitry Andric 
8300b57cec5SDimitry Andric /// ActOnCXXThrow - Parse throw expressions.
8310b57cec5SDimitry Andric ExprResult
ActOnCXXThrow(Scope * S,SourceLocation OpLoc,Expr * Ex)8320b57cec5SDimitry Andric Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) {
8330b57cec5SDimitry Andric   bool IsThrownVarInScope = false;
8340b57cec5SDimitry Andric   if (Ex) {
8350b57cec5SDimitry Andric     // C++0x [class.copymove]p31:
8360b57cec5SDimitry Andric     //   When certain criteria are met, an implementation is allowed to omit the
8370b57cec5SDimitry Andric     //   copy/move construction of a class object [...]
8380b57cec5SDimitry Andric     //
8390b57cec5SDimitry Andric     //     - in a throw-expression, when the operand is the name of a
8400b57cec5SDimitry Andric     //       non-volatile automatic object (other than a function or catch-
8410b57cec5SDimitry Andric     //       clause parameter) whose scope does not extend beyond the end of the
8420b57cec5SDimitry Andric     //       innermost enclosing try-block (if there is one), the copy/move
8430b57cec5SDimitry Andric     //       operation from the operand to the exception object (15.1) can be
8440b57cec5SDimitry Andric     //       omitted by constructing the automatic object directly into the
8450b57cec5SDimitry Andric     //       exception object
846cb14a3feSDimitry Andric     if (const auto *DRE = dyn_cast<DeclRefExpr>(Ex->IgnoreParens()))
847cb14a3feSDimitry Andric       if (const auto *Var = dyn_cast<VarDecl>(DRE->getDecl());
848cb14a3feSDimitry Andric           Var && Var->hasLocalStorage() &&
849cb14a3feSDimitry Andric           !Var->getType().isVolatileQualified()) {
8500b57cec5SDimitry Andric         for (; S; S = S->getParent()) {
8510b57cec5SDimitry Andric           if (S->isDeclScope(Var)) {
8520b57cec5SDimitry Andric             IsThrownVarInScope = true;
8530b57cec5SDimitry Andric             break;
8540b57cec5SDimitry Andric           }
8550b57cec5SDimitry Andric 
85681ad6265SDimitry Andric           // FIXME: Many of the scope checks here seem incorrect.
8570b57cec5SDimitry Andric           if (S->getFlags() &
8580b57cec5SDimitry Andric               (Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
85981ad6265SDimitry Andric                Scope::ObjCMethodScope | Scope::TryScope))
8600b57cec5SDimitry Andric             break;
8610b57cec5SDimitry Andric         }
8620b57cec5SDimitry Andric       }
8630b57cec5SDimitry Andric   }
8640b57cec5SDimitry Andric 
8650b57cec5SDimitry Andric   return BuildCXXThrow(OpLoc, Ex, IsThrownVarInScope);
8660b57cec5SDimitry Andric }
8670b57cec5SDimitry Andric 
BuildCXXThrow(SourceLocation OpLoc,Expr * Ex,bool IsThrownVarInScope)8680b57cec5SDimitry Andric ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
8690b57cec5SDimitry Andric                                bool IsThrownVarInScope) {
8705f757f3fSDimitry Andric   const llvm::Triple &T = Context.getTargetInfo().getTriple();
8715f757f3fSDimitry Andric   const bool IsOpenMPGPUTarget =
8725f757f3fSDimitry Andric       getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN());
8735f757f3fSDimitry Andric   // Don't report an error if 'throw' is used in system headers or in an OpenMP
8745f757f3fSDimitry Andric   // target region compiled for a GPU architecture.
8755f757f3fSDimitry Andric   if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions &&
8760b57cec5SDimitry Andric       !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) {
8770b57cec5SDimitry Andric     // Delay error emission for the OpenMP device code.
8780b57cec5SDimitry Andric     targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw";
8790b57cec5SDimitry Andric   }
8800b57cec5SDimitry Andric 
8815f757f3fSDimitry Andric   // In OpenMP target regions, we replace 'throw' with a trap on GPU targets.
8825f757f3fSDimitry Andric   if (IsOpenMPGPUTarget)
8835f757f3fSDimitry Andric     targetDiag(OpLoc, diag::warn_throw_not_valid_on_target) << T.str();
8845f757f3fSDimitry Andric 
8850b57cec5SDimitry Andric   // Exceptions aren't allowed in CUDA device code.
8860b57cec5SDimitry Andric   if (getLangOpts().CUDA)
8870b57cec5SDimitry Andric     CUDADiagIfDeviceCode(OpLoc, diag::err_cuda_device_exceptions)
8880b57cec5SDimitry Andric         << "throw" << CurrentCUDATarget();
8890b57cec5SDimitry Andric 
8900b57cec5SDimitry Andric   if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
8910b57cec5SDimitry Andric     Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw";
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   if (Ex && !Ex->isTypeDependent()) {
8940b57cec5SDimitry Andric     // Initialize the exception result.  This implicitly weeds out
8950b57cec5SDimitry Andric     // abstract types or types with inaccessible copy constructors.
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric     // C++0x [class.copymove]p31:
8980b57cec5SDimitry Andric     //   When certain criteria are met, an implementation is allowed to omit the
8990b57cec5SDimitry Andric     //   copy/move construction of a class object [...]
9000b57cec5SDimitry Andric     //
9010b57cec5SDimitry Andric     //     - in a throw-expression, when the operand is the name of a
9020b57cec5SDimitry Andric     //       non-volatile automatic object (other than a function or
9030b57cec5SDimitry Andric     //       catch-clause
9040b57cec5SDimitry Andric     //       parameter) whose scope does not extend beyond the end of the
9050b57cec5SDimitry Andric     //       innermost enclosing try-block (if there is one), the copy/move
9060b57cec5SDimitry Andric     //       operation from the operand to the exception object (15.1) can be
9070b57cec5SDimitry Andric     //       omitted by constructing the automatic object directly into the
9080b57cec5SDimitry Andric     //       exception object
909fe6060f1SDimitry Andric     NamedReturnInfo NRInfo =
910fe6060f1SDimitry Andric         IsThrownVarInScope ? getNamedReturnInfo(Ex) : NamedReturnInfo();
911fe6060f1SDimitry Andric 
912fe6060f1SDimitry Andric     QualType ExceptionObjectTy = Context.getExceptionObjectType(Ex->getType());
913fe6060f1SDimitry Andric     if (CheckCXXThrowOperand(OpLoc, ExceptionObjectTy, Ex))
914fe6060f1SDimitry Andric       return ExprError();
9150b57cec5SDimitry Andric 
91628a41182SDimitry Andric     InitializedEntity Entity =
91728a41182SDimitry Andric         InitializedEntity::InitializeException(OpLoc, ExceptionObjectTy);
918fe6060f1SDimitry Andric     ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRInfo, Ex);
9190b57cec5SDimitry Andric     if (Res.isInvalid())
9200b57cec5SDimitry Andric       return ExprError();
9210b57cec5SDimitry Andric     Ex = Res.get();
9220b57cec5SDimitry Andric   }
9230b57cec5SDimitry Andric 
924e8d8bef9SDimitry Andric   // PPC MMA non-pointer types are not allowed as throw expr types.
925e8d8bef9SDimitry Andric   if (Ex && Context.getTargetInfo().getTriple().isPPC64())
926e8d8bef9SDimitry Andric     CheckPPCMMAType(Ex->getType(), Ex->getBeginLoc());
927e8d8bef9SDimitry Andric 
9280b57cec5SDimitry Andric   return new (Context)
9290b57cec5SDimitry Andric       CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope);
9300b57cec5SDimitry Andric }
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric static void
collectPublicBases(CXXRecordDecl * RD,llvm::DenseMap<CXXRecordDecl *,unsigned> & SubobjectsSeen,llvm::SmallPtrSetImpl<CXXRecordDecl * > & VBases,llvm::SetVector<CXXRecordDecl * > & PublicSubobjectsSeen,bool ParentIsPublic)9330b57cec5SDimitry Andric collectPublicBases(CXXRecordDecl *RD,
9340b57cec5SDimitry Andric                    llvm::DenseMap<CXXRecordDecl *, unsigned> &SubobjectsSeen,
9350b57cec5SDimitry Andric                    llvm::SmallPtrSetImpl<CXXRecordDecl *> &VBases,
9360b57cec5SDimitry Andric                    llvm::SetVector<CXXRecordDecl *> &PublicSubobjectsSeen,
9370b57cec5SDimitry Andric                    bool ParentIsPublic) {
9380b57cec5SDimitry Andric   for (const CXXBaseSpecifier &BS : RD->bases()) {
9390b57cec5SDimitry Andric     CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl();
9400b57cec5SDimitry Andric     bool NewSubobject;
9410b57cec5SDimitry Andric     // Virtual bases constitute the same subobject.  Non-virtual bases are
9420b57cec5SDimitry Andric     // always distinct subobjects.
9430b57cec5SDimitry Andric     if (BS.isVirtual())
9440b57cec5SDimitry Andric       NewSubobject = VBases.insert(BaseDecl).second;
9450b57cec5SDimitry Andric     else
9460b57cec5SDimitry Andric       NewSubobject = true;
9470b57cec5SDimitry Andric 
9480b57cec5SDimitry Andric     if (NewSubobject)
9490b57cec5SDimitry Andric       ++SubobjectsSeen[BaseDecl];
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric     // Only add subobjects which have public access throughout the entire chain.
9520b57cec5SDimitry Andric     bool PublicPath = ParentIsPublic && BS.getAccessSpecifier() == AS_public;
9530b57cec5SDimitry Andric     if (PublicPath)
9540b57cec5SDimitry Andric       PublicSubobjectsSeen.insert(BaseDecl);
9550b57cec5SDimitry Andric 
9560b57cec5SDimitry Andric     // Recurse on to each base subobject.
9570b57cec5SDimitry Andric     collectPublicBases(BaseDecl, SubobjectsSeen, VBases, PublicSubobjectsSeen,
9580b57cec5SDimitry Andric                        PublicPath);
9590b57cec5SDimitry Andric   }
9600b57cec5SDimitry Andric }
9610b57cec5SDimitry Andric 
getUnambiguousPublicSubobjects(CXXRecordDecl * RD,llvm::SmallVectorImpl<CXXRecordDecl * > & Objects)9620b57cec5SDimitry Andric static void getUnambiguousPublicSubobjects(
9630b57cec5SDimitry Andric     CXXRecordDecl *RD, llvm::SmallVectorImpl<CXXRecordDecl *> &Objects) {
9640b57cec5SDimitry Andric   llvm::DenseMap<CXXRecordDecl *, unsigned> SubobjectsSeen;
9650b57cec5SDimitry Andric   llvm::SmallSet<CXXRecordDecl *, 2> VBases;
9660b57cec5SDimitry Andric   llvm::SetVector<CXXRecordDecl *> PublicSubobjectsSeen;
9670b57cec5SDimitry Andric   SubobjectsSeen[RD] = 1;
9680b57cec5SDimitry Andric   PublicSubobjectsSeen.insert(RD);
9690b57cec5SDimitry Andric   collectPublicBases(RD, SubobjectsSeen, VBases, PublicSubobjectsSeen,
9700b57cec5SDimitry Andric                      /*ParentIsPublic=*/true);
9710b57cec5SDimitry Andric 
9720b57cec5SDimitry Andric   for (CXXRecordDecl *PublicSubobject : PublicSubobjectsSeen) {
9730b57cec5SDimitry Andric     // Skip ambiguous objects.
9740b57cec5SDimitry Andric     if (SubobjectsSeen[PublicSubobject] > 1)
9750b57cec5SDimitry Andric       continue;
9760b57cec5SDimitry Andric 
9770b57cec5SDimitry Andric     Objects.push_back(PublicSubobject);
9780b57cec5SDimitry Andric   }
9790b57cec5SDimitry Andric }
9800b57cec5SDimitry Andric 
9810b57cec5SDimitry Andric /// CheckCXXThrowOperand - Validate the operand of a throw.
CheckCXXThrowOperand(SourceLocation ThrowLoc,QualType ExceptionObjectTy,Expr * E)9820b57cec5SDimitry Andric bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc,
9830b57cec5SDimitry Andric                                 QualType ExceptionObjectTy, Expr *E) {
9840b57cec5SDimitry Andric   //   If the type of the exception would be an incomplete type or a pointer
9850b57cec5SDimitry Andric   //   to an incomplete type other than (cv) void the program is ill-formed.
9860b57cec5SDimitry Andric   QualType Ty = ExceptionObjectTy;
9870b57cec5SDimitry Andric   bool isPointer = false;
9880b57cec5SDimitry Andric   if (const PointerType* Ptr = Ty->getAs<PointerType>()) {
9890b57cec5SDimitry Andric     Ty = Ptr->getPointeeType();
9900b57cec5SDimitry Andric     isPointer = true;
9910b57cec5SDimitry Andric   }
99206c3fb27SDimitry Andric 
99306c3fb27SDimitry Andric   // Cannot throw WebAssembly reference type.
99406c3fb27SDimitry Andric   if (Ty.isWebAssemblyReferenceType()) {
99506c3fb27SDimitry Andric     Diag(ThrowLoc, diag::err_wasm_reftype_tc) << 0 << E->getSourceRange();
99606c3fb27SDimitry Andric     return true;
99706c3fb27SDimitry Andric   }
99806c3fb27SDimitry Andric 
99906c3fb27SDimitry Andric   // Cannot throw WebAssembly table.
100006c3fb27SDimitry Andric   if (isPointer && Ty.isWebAssemblyReferenceType()) {
100106c3fb27SDimitry Andric     Diag(ThrowLoc, diag::err_wasm_table_art) << 2 << E->getSourceRange();
100206c3fb27SDimitry Andric     return true;
100306c3fb27SDimitry Andric   }
100406c3fb27SDimitry Andric 
10050b57cec5SDimitry Andric   if (!isPointer || !Ty->isVoidType()) {
10060b57cec5SDimitry Andric     if (RequireCompleteType(ThrowLoc, Ty,
10070b57cec5SDimitry Andric                             isPointer ? diag::err_throw_incomplete_ptr
10080b57cec5SDimitry Andric                                       : diag::err_throw_incomplete,
10090b57cec5SDimitry Andric                             E->getSourceRange()))
10100b57cec5SDimitry Andric       return true;
10110b57cec5SDimitry Andric 
10125ffd83dbSDimitry Andric     if (!isPointer && Ty->isSizelessType()) {
10135ffd83dbSDimitry Andric       Diag(ThrowLoc, diag::err_throw_sizeless) << Ty << E->getSourceRange();
10145ffd83dbSDimitry Andric       return true;
10155ffd83dbSDimitry Andric     }
10165ffd83dbSDimitry Andric 
10170b57cec5SDimitry Andric     if (RequireNonAbstractType(ThrowLoc, ExceptionObjectTy,
10180b57cec5SDimitry Andric                                diag::err_throw_abstract_type, E))
10190b57cec5SDimitry Andric       return true;
10200b57cec5SDimitry Andric   }
10210b57cec5SDimitry Andric 
10220b57cec5SDimitry Andric   // If the exception has class type, we need additional handling.
10230b57cec5SDimitry Andric   CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
10240b57cec5SDimitry Andric   if (!RD)
10250b57cec5SDimitry Andric     return false;
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric   // If we are throwing a polymorphic class type or pointer thereof,
10280b57cec5SDimitry Andric   // exception handling will make use of the vtable.
10290b57cec5SDimitry Andric   MarkVTableUsed(ThrowLoc, RD);
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric   // If a pointer is thrown, the referenced object will not be destroyed.
10320b57cec5SDimitry Andric   if (isPointer)
10330b57cec5SDimitry Andric     return false;
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric   // If the class has a destructor, we must be able to call it.
10360b57cec5SDimitry Andric   if (!RD->hasIrrelevantDestructor()) {
10370b57cec5SDimitry Andric     if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) {
10380b57cec5SDimitry Andric       MarkFunctionReferenced(E->getExprLoc(), Destructor);
10390b57cec5SDimitry Andric       CheckDestructorAccess(E->getExprLoc(), Destructor,
10400b57cec5SDimitry Andric                             PDiag(diag::err_access_dtor_exception) << Ty);
10410b57cec5SDimitry Andric       if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
10420b57cec5SDimitry Andric         return true;
10430b57cec5SDimitry Andric     }
10440b57cec5SDimitry Andric   }
10450b57cec5SDimitry Andric 
10460b57cec5SDimitry Andric   // The MSVC ABI creates a list of all types which can catch the exception
10470b57cec5SDimitry Andric   // object.  This list also references the appropriate copy constructor to call
10480b57cec5SDimitry Andric   // if the object is caught by value and has a non-trivial copy constructor.
10490b57cec5SDimitry Andric   if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
10500b57cec5SDimitry Andric     // We are only interested in the public, unambiguous bases contained within
10510b57cec5SDimitry Andric     // the exception object.  Bases which are ambiguous or otherwise
10520b57cec5SDimitry Andric     // inaccessible are not catchable types.
10530b57cec5SDimitry Andric     llvm::SmallVector<CXXRecordDecl *, 2> UnambiguousPublicSubobjects;
10540b57cec5SDimitry Andric     getUnambiguousPublicSubobjects(RD, UnambiguousPublicSubobjects);
10550b57cec5SDimitry Andric 
10560b57cec5SDimitry Andric     for (CXXRecordDecl *Subobject : UnambiguousPublicSubobjects) {
10570b57cec5SDimitry Andric       // Attempt to lookup the copy constructor.  Various pieces of machinery
10580b57cec5SDimitry Andric       // will spring into action, like template instantiation, which means this
10590b57cec5SDimitry Andric       // cannot be a simple walk of the class's decls.  Instead, we must perform
10600b57cec5SDimitry Andric       // lookup and overload resolution.
10610b57cec5SDimitry Andric       CXXConstructorDecl *CD = LookupCopyingConstructor(Subobject, 0);
1062480093f4SDimitry Andric       if (!CD || CD->isDeleted())
10630b57cec5SDimitry Andric         continue;
10640b57cec5SDimitry Andric 
10650b57cec5SDimitry Andric       // Mark the constructor referenced as it is used by this throw expression.
10660b57cec5SDimitry Andric       MarkFunctionReferenced(E->getExprLoc(), CD);
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric       // Skip this copy constructor if it is trivial, we don't need to record it
10690b57cec5SDimitry Andric       // in the catchable type data.
10700b57cec5SDimitry Andric       if (CD->isTrivial())
10710b57cec5SDimitry Andric         continue;
10720b57cec5SDimitry Andric 
10730b57cec5SDimitry Andric       // The copy constructor is non-trivial, create a mapping from this class
10740b57cec5SDimitry Andric       // type to this constructor.
10750b57cec5SDimitry Andric       // N.B.  The selection of copy constructor is not sensitive to this
10760b57cec5SDimitry Andric       // particular throw-site.  Lookup will be performed at the catch-site to
10770b57cec5SDimitry Andric       // ensure that the copy constructor is, in fact, accessible (via
10780b57cec5SDimitry Andric       // friendship or any other means).
10790b57cec5SDimitry Andric       Context.addCopyConstructorForExceptionObject(Subobject, CD);
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric       // We don't keep the instantiated default argument expressions around so
10820b57cec5SDimitry Andric       // we must rebuild them here.
10830b57cec5SDimitry Andric       for (unsigned I = 1, E = CD->getNumParams(); I != E; ++I) {
10840b57cec5SDimitry Andric         if (CheckCXXDefaultArgExpr(ThrowLoc, CD, CD->getParamDecl(I)))
10850b57cec5SDimitry Andric           return true;
10860b57cec5SDimitry Andric       }
10870b57cec5SDimitry Andric     }
10880b57cec5SDimitry Andric   }
10890b57cec5SDimitry Andric 
10900b57cec5SDimitry Andric   // Under the Itanium C++ ABI, memory for the exception object is allocated by
10910b57cec5SDimitry Andric   // the runtime with no ability for the compiler to request additional
10920b57cec5SDimitry Andric   // alignment. Warn if the exception type requires alignment beyond the minimum
10930b57cec5SDimitry Andric   // guaranteed by the target C++ runtime.
10940b57cec5SDimitry Andric   if (Context.getTargetInfo().getCXXABI().isItaniumFamily()) {
10950b57cec5SDimitry Andric     CharUnits TypeAlign = Context.getTypeAlignInChars(Ty);
10960b57cec5SDimitry Andric     CharUnits ExnObjAlign = Context.getExnObjectAlignment();
10970b57cec5SDimitry Andric     if (ExnObjAlign < TypeAlign) {
10980b57cec5SDimitry Andric       Diag(ThrowLoc, diag::warn_throw_underaligned_obj);
10990b57cec5SDimitry Andric       Diag(ThrowLoc, diag::note_throw_underaligned_obj)
11000b57cec5SDimitry Andric           << Ty << (unsigned)TypeAlign.getQuantity()
11010b57cec5SDimitry Andric           << (unsigned)ExnObjAlign.getQuantity();
11020b57cec5SDimitry Andric     }
11030b57cec5SDimitry Andric   }
11045f757f3fSDimitry Andric   if (!isPointer && getLangOpts().AssumeNothrowExceptionDtor) {
11055f757f3fSDimitry Andric     if (CXXDestructorDecl *Dtor = RD->getDestructor()) {
11065f757f3fSDimitry Andric       auto Ty = Dtor->getType();
11075f757f3fSDimitry Andric       if (auto *FT = Ty.getTypePtr()->getAs<FunctionProtoType>()) {
11085f757f3fSDimitry Andric         if (!isUnresolvedExceptionSpec(FT->getExceptionSpecType()) &&
11095f757f3fSDimitry Andric             !FT->isNothrow())
11105f757f3fSDimitry Andric           Diag(ThrowLoc, diag::err_throw_object_throwing_dtor) << RD;
11115f757f3fSDimitry Andric       }
11125f757f3fSDimitry Andric     }
11135f757f3fSDimitry Andric   }
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric   return false;
11160b57cec5SDimitry Andric }
11170b57cec5SDimitry Andric 
adjustCVQualifiersForCXXThisWithinLambda(ArrayRef<FunctionScopeInfo * > FunctionScopes,QualType ThisTy,DeclContext * CurSemaContext,ASTContext & ASTCtx)11180b57cec5SDimitry Andric static QualType adjustCVQualifiersForCXXThisWithinLambda(
11190b57cec5SDimitry Andric     ArrayRef<FunctionScopeInfo *> FunctionScopes, QualType ThisTy,
11200b57cec5SDimitry Andric     DeclContext *CurSemaContext, ASTContext &ASTCtx) {
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric   QualType ClassType = ThisTy->getPointeeType();
11230b57cec5SDimitry Andric   LambdaScopeInfo *CurLSI = nullptr;
11240b57cec5SDimitry Andric   DeclContext *CurDC = CurSemaContext;
11250b57cec5SDimitry Andric 
11260b57cec5SDimitry Andric   // Iterate through the stack of lambdas starting from the innermost lambda to
11270b57cec5SDimitry Andric   // the outermost lambda, checking if '*this' is ever captured by copy - since
11280b57cec5SDimitry Andric   // that could change the cv-qualifiers of the '*this' object.
11290b57cec5SDimitry Andric   // The object referred to by '*this' starts out with the cv-qualifiers of its
11300b57cec5SDimitry Andric   // member function.  We then start with the innermost lambda and iterate
11310b57cec5SDimitry Andric   // outward checking to see if any lambda performs a by-copy capture of '*this'
11320b57cec5SDimitry Andric   // - and if so, any nested lambda must respect the 'constness' of that
11330b57cec5SDimitry Andric   // capturing lamdbda's call operator.
11340b57cec5SDimitry Andric   //
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   // Since the FunctionScopeInfo stack is representative of the lexical
11370b57cec5SDimitry Andric   // nesting of the lambda expressions during initial parsing (and is the best
11380b57cec5SDimitry Andric   // place for querying information about captures about lambdas that are
11390b57cec5SDimitry Andric   // partially processed) and perhaps during instantiation of function templates
11400b57cec5SDimitry Andric   // that contain lambda expressions that need to be transformed BUT not
11410b57cec5SDimitry Andric   // necessarily during instantiation of a nested generic lambda's function call
11420b57cec5SDimitry Andric   // operator (which might even be instantiated at the end of the TU) - at which
11430b57cec5SDimitry Andric   // time the DeclContext tree is mature enough to query capture information
11440b57cec5SDimitry Andric   // reliably - we use a two pronged approach to walk through all the lexically
11450b57cec5SDimitry Andric   // enclosing lambda expressions:
11460b57cec5SDimitry Andric   //
11470b57cec5SDimitry Andric   //  1) Climb down the FunctionScopeInfo stack as long as each item represents
11480b57cec5SDimitry Andric   //  a Lambda (i.e. LambdaScopeInfo) AND each LSI's 'closure-type' is lexically
11490b57cec5SDimitry Andric   //  enclosed by the call-operator of the LSI below it on the stack (while
11500b57cec5SDimitry Andric   //  tracking the enclosing DC for step 2 if needed).  Note the topmost LSI on
11510b57cec5SDimitry Andric   //  the stack represents the innermost lambda.
11520b57cec5SDimitry Andric   //
11530b57cec5SDimitry Andric   //  2) If we run out of enclosing LSI's, check if the enclosing DeclContext
11540b57cec5SDimitry Andric   //  represents a lambda's call operator.  If it does, we must be instantiating
11550b57cec5SDimitry Andric   //  a generic lambda's call operator (represented by the Current LSI, and
11560b57cec5SDimitry Andric   //  should be the only scenario where an inconsistency between the LSI and the
11570b57cec5SDimitry Andric   //  DeclContext should occur), so climb out the DeclContexts if they
11580b57cec5SDimitry Andric   //  represent lambdas, while querying the corresponding closure types
11590b57cec5SDimitry Andric   //  regarding capture information.
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric   // 1) Climb down the function scope info stack.
11620b57cec5SDimitry Andric   for (int I = FunctionScopes.size();
11630b57cec5SDimitry Andric        I-- && isa<LambdaScopeInfo>(FunctionScopes[I]) &&
11640b57cec5SDimitry Andric        (!CurLSI || !CurLSI->Lambda || CurLSI->Lambda->getDeclContext() ==
11650b57cec5SDimitry Andric                        cast<LambdaScopeInfo>(FunctionScopes[I])->CallOperator);
11660b57cec5SDimitry Andric        CurDC = getLambdaAwareParentOfDeclContext(CurDC)) {
11670b57cec5SDimitry Andric     CurLSI = cast<LambdaScopeInfo>(FunctionScopes[I]);
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric     if (!CurLSI->isCXXThisCaptured())
11700b57cec5SDimitry Andric         continue;
11710b57cec5SDimitry Andric 
11720b57cec5SDimitry Andric     auto C = CurLSI->getCXXThisCapture();
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric     if (C.isCopyCapture()) {
11755f757f3fSDimitry Andric       if (CurLSI->lambdaCaptureShouldBeConst())
11760b57cec5SDimitry Andric         ClassType.addConst();
11770b57cec5SDimitry Andric       return ASTCtx.getPointerType(ClassType);
11780b57cec5SDimitry Andric     }
11790b57cec5SDimitry Andric   }
11800b57cec5SDimitry Andric 
1181349cc55cSDimitry Andric   // 2) We've run out of ScopeInfos but check 1. if CurDC is a lambda (which
1182349cc55cSDimitry Andric   //    can happen during instantiation of its nested generic lambda call
1183349cc55cSDimitry Andric   //    operator); 2. if we're in a lambda scope (lambda body).
1184349cc55cSDimitry Andric   if (CurLSI && isLambdaCallOperator(CurDC)) {
11850b57cec5SDimitry Andric     assert(isGenericLambdaCallOperatorSpecialization(CurLSI->CallOperator) &&
11860b57cec5SDimitry Andric            "While computing 'this' capture-type for a generic lambda, when we "
11870b57cec5SDimitry Andric            "run out of enclosing LSI's, yet the enclosing DC is a "
11880b57cec5SDimitry Andric            "lambda-call-operator we must be (i.e. Current LSI) in a generic "
11890b57cec5SDimitry Andric            "lambda call oeprator");
11900b57cec5SDimitry Andric     assert(CurDC == getLambdaAwareParentOfDeclContext(CurLSI->CallOperator));
11910b57cec5SDimitry Andric 
11920b57cec5SDimitry Andric     auto IsThisCaptured =
11930b57cec5SDimitry Andric         [](CXXRecordDecl *Closure, bool &IsByCopy, bool &IsConst) {
11940b57cec5SDimitry Andric       IsConst = false;
11950b57cec5SDimitry Andric       IsByCopy = false;
11960b57cec5SDimitry Andric       for (auto &&C : Closure->captures()) {
11970b57cec5SDimitry Andric         if (C.capturesThis()) {
11980b57cec5SDimitry Andric           if (C.getCaptureKind() == LCK_StarThis)
11990b57cec5SDimitry Andric             IsByCopy = true;
12000b57cec5SDimitry Andric           if (Closure->getLambdaCallOperator()->isConst())
12010b57cec5SDimitry Andric             IsConst = true;
12020b57cec5SDimitry Andric           return true;
12030b57cec5SDimitry Andric         }
12040b57cec5SDimitry Andric       }
12050b57cec5SDimitry Andric       return false;
12060b57cec5SDimitry Andric     };
12070b57cec5SDimitry Andric 
12080b57cec5SDimitry Andric     bool IsByCopyCapture = false;
12090b57cec5SDimitry Andric     bool IsConstCapture = false;
12100b57cec5SDimitry Andric     CXXRecordDecl *Closure = cast<CXXRecordDecl>(CurDC->getParent());
12110b57cec5SDimitry Andric     while (Closure &&
12120b57cec5SDimitry Andric            IsThisCaptured(Closure, IsByCopyCapture, IsConstCapture)) {
12130b57cec5SDimitry Andric       if (IsByCopyCapture) {
12140b57cec5SDimitry Andric         if (IsConstCapture)
12150b57cec5SDimitry Andric           ClassType.addConst();
12160b57cec5SDimitry Andric         return ASTCtx.getPointerType(ClassType);
12170b57cec5SDimitry Andric       }
12180b57cec5SDimitry Andric       Closure = isLambdaCallOperator(Closure->getParent())
12190b57cec5SDimitry Andric                     ? cast<CXXRecordDecl>(Closure->getParent()->getParent())
12200b57cec5SDimitry Andric                     : nullptr;
12210b57cec5SDimitry Andric     }
12220b57cec5SDimitry Andric   }
12230b57cec5SDimitry Andric   return ASTCtx.getPointerType(ClassType);
12240b57cec5SDimitry Andric }
12250b57cec5SDimitry Andric 
getCurrentThisType()12260b57cec5SDimitry Andric QualType Sema::getCurrentThisType() {
12270b57cec5SDimitry Andric   DeclContext *DC = getFunctionLevelDeclContext();
12280b57cec5SDimitry Andric   QualType ThisTy = CXXThisTypeOverride;
12290b57cec5SDimitry Andric 
12300b57cec5SDimitry Andric   if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC)) {
12315f757f3fSDimitry Andric     if (method && method->isImplicitObjectMemberFunction())
12325f757f3fSDimitry Andric       ThisTy = method->getThisType().getNonReferenceType();
12330b57cec5SDimitry Andric   }
12340b57cec5SDimitry Andric 
12355f757f3fSDimitry Andric   if (ThisTy.isNull() && isLambdaCallWithImplicitObjectParameter(CurContext) &&
1236fe6060f1SDimitry Andric       inTemplateInstantiation() && isa<CXXRecordDecl>(DC)) {
12370b57cec5SDimitry Andric 
12380b57cec5SDimitry Andric     // This is a lambda call operator that is being instantiated as a default
12390b57cec5SDimitry Andric     // initializer. DC must point to the enclosing class type, so we can recover
12400b57cec5SDimitry Andric     // the 'this' type from it.
12410b57cec5SDimitry Andric     QualType ClassTy = Context.getTypeDeclType(cast<CXXRecordDecl>(DC));
12420b57cec5SDimitry Andric     // There are no cv-qualifiers for 'this' within default initializers,
12430b57cec5SDimitry Andric     // per [expr.prim.general]p4.
12440b57cec5SDimitry Andric     ThisTy = Context.getPointerType(ClassTy);
12450b57cec5SDimitry Andric   }
12460b57cec5SDimitry Andric 
12470b57cec5SDimitry Andric   // If we are within a lambda's call operator, the cv-qualifiers of 'this'
12480b57cec5SDimitry Andric   // might need to be adjusted if the lambda or any of its enclosing lambda's
12490b57cec5SDimitry Andric   // captures '*this' by copy.
12500b57cec5SDimitry Andric   if (!ThisTy.isNull() && isLambdaCallOperator(CurContext))
12510b57cec5SDimitry Andric     return adjustCVQualifiersForCXXThisWithinLambda(FunctionScopes, ThisTy,
12520b57cec5SDimitry Andric                                                     CurContext, Context);
12530b57cec5SDimitry Andric   return ThisTy;
12540b57cec5SDimitry Andric }
12550b57cec5SDimitry Andric 
CXXThisScopeRAII(Sema & S,Decl * ContextDecl,Qualifiers CXXThisTypeQuals,bool Enabled)12560b57cec5SDimitry Andric Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S,
12570b57cec5SDimitry Andric                                          Decl *ContextDecl,
12580b57cec5SDimitry Andric                                          Qualifiers CXXThisTypeQuals,
12590b57cec5SDimitry Andric                                          bool Enabled)
12600b57cec5SDimitry Andric   : S(S), OldCXXThisTypeOverride(S.CXXThisTypeOverride), Enabled(false)
12610b57cec5SDimitry Andric {
12620b57cec5SDimitry Andric   if (!Enabled || !ContextDecl)
12630b57cec5SDimitry Andric     return;
12640b57cec5SDimitry Andric 
12650b57cec5SDimitry Andric   CXXRecordDecl *Record = nullptr;
12660b57cec5SDimitry Andric   if (ClassTemplateDecl *Template = dyn_cast<ClassTemplateDecl>(ContextDecl))
12670b57cec5SDimitry Andric     Record = Template->getTemplatedDecl();
12680b57cec5SDimitry Andric   else
12690b57cec5SDimitry Andric     Record = cast<CXXRecordDecl>(ContextDecl);
12700b57cec5SDimitry Andric 
12710b57cec5SDimitry Andric   QualType T = S.Context.getRecordType(Record);
12720b57cec5SDimitry Andric   T = S.getASTContext().getQualifiedType(T, CXXThisTypeQuals);
12730b57cec5SDimitry Andric 
12745f757f3fSDimitry Andric   S.CXXThisTypeOverride =
12755f757f3fSDimitry Andric       S.Context.getLangOpts().HLSL ? T : S.Context.getPointerType(T);
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric   this->Enabled = true;
12780b57cec5SDimitry Andric }
12790b57cec5SDimitry Andric 
12800b57cec5SDimitry Andric 
~CXXThisScopeRAII()12810b57cec5SDimitry Andric Sema::CXXThisScopeRAII::~CXXThisScopeRAII() {
12820b57cec5SDimitry Andric   if (Enabled) {
12830b57cec5SDimitry Andric     S.CXXThisTypeOverride = OldCXXThisTypeOverride;
12840b57cec5SDimitry Andric   }
12850b57cec5SDimitry Andric }
12860b57cec5SDimitry Andric 
buildLambdaThisCaptureFixit(Sema & Sema,LambdaScopeInfo * LSI)1287fe6060f1SDimitry Andric static void buildLambdaThisCaptureFixit(Sema &Sema, LambdaScopeInfo *LSI) {
1288fe6060f1SDimitry Andric   SourceLocation DiagLoc = LSI->IntroducerRange.getEnd();
1289fe6060f1SDimitry Andric   assert(!LSI->isCXXThisCaptured());
1290fe6060f1SDimitry Andric   //  [=, this] {};   // until C++20: Error: this when = is the default
1291fe6060f1SDimitry Andric   if (LSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval &&
1292fe6060f1SDimitry Andric       !Sema.getLangOpts().CPlusPlus20)
1293fe6060f1SDimitry Andric     return;
1294fe6060f1SDimitry Andric   Sema.Diag(DiagLoc, diag::note_lambda_this_capture_fixit)
1295fe6060f1SDimitry Andric       << FixItHint::CreateInsertion(
1296fe6060f1SDimitry Andric              DiagLoc, LSI->NumExplicitCaptures > 0 ? ", this" : "this");
1297fe6060f1SDimitry Andric }
1298fe6060f1SDimitry Andric 
CheckCXXThisCapture(SourceLocation Loc,const bool Explicit,bool BuildAndDiagnose,const unsigned * const FunctionScopeIndexToStopAt,const bool ByCopy)12990b57cec5SDimitry Andric bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
13000b57cec5SDimitry Andric     bool BuildAndDiagnose, const unsigned *const FunctionScopeIndexToStopAt,
13010b57cec5SDimitry Andric     const bool ByCopy) {
13020b57cec5SDimitry Andric   // We don't need to capture this in an unevaluated context.
13030b57cec5SDimitry Andric   if (isUnevaluatedContext() && !Explicit)
13040b57cec5SDimitry Andric     return true;
13050b57cec5SDimitry Andric 
13060b57cec5SDimitry Andric   assert((!ByCopy || Explicit) && "cannot implicitly capture *this by value");
13070b57cec5SDimitry Andric 
13080b57cec5SDimitry Andric   const int MaxFunctionScopesIndex = FunctionScopeIndexToStopAt
13090b57cec5SDimitry Andric                                          ? *FunctionScopeIndexToStopAt
13100b57cec5SDimitry Andric                                          : FunctionScopes.size() - 1;
13110b57cec5SDimitry Andric 
13120b57cec5SDimitry Andric   // Check that we can capture the *enclosing object* (referred to by '*this')
13130b57cec5SDimitry Andric   // by the capturing-entity/closure (lambda/block/etc) at
13140b57cec5SDimitry Andric   // MaxFunctionScopesIndex-deep on the FunctionScopes stack.
13150b57cec5SDimitry Andric 
13160b57cec5SDimitry Andric   // Note: The *enclosing object* can only be captured by-value by a
13170b57cec5SDimitry Andric   // closure that is a lambda, using the explicit notation:
13180b57cec5SDimitry Andric   //    [*this] { ... }.
13190b57cec5SDimitry Andric   // Every other capture of the *enclosing object* results in its by-reference
13200b57cec5SDimitry Andric   // capture.
13210b57cec5SDimitry Andric 
13220b57cec5SDimitry Andric   // For a closure 'L' (at MaxFunctionScopesIndex in the FunctionScopes
13230b57cec5SDimitry Andric   // stack), we can capture the *enclosing object* only if:
13240b57cec5SDimitry Andric   // - 'L' has an explicit byref or byval capture of the *enclosing object*
13250b57cec5SDimitry Andric   // -  or, 'L' has an implicit capture.
13260b57cec5SDimitry Andric   // AND
13270b57cec5SDimitry Andric   //   -- there is no enclosing closure
13280b57cec5SDimitry Andric   //   -- or, there is some enclosing closure 'E' that has already captured the
13290b57cec5SDimitry Andric   //      *enclosing object*, and every intervening closure (if any) between 'E'
13300b57cec5SDimitry Andric   //      and 'L' can implicitly capture the *enclosing object*.
13310b57cec5SDimitry Andric   //   -- or, every enclosing closure can implicitly capture the
13320b57cec5SDimitry Andric   //      *enclosing object*
13330b57cec5SDimitry Andric 
13340b57cec5SDimitry Andric 
13350b57cec5SDimitry Andric   unsigned NumCapturingClosures = 0;
13360b57cec5SDimitry Andric   for (int idx = MaxFunctionScopesIndex; idx >= 0; idx--) {
13370b57cec5SDimitry Andric     if (CapturingScopeInfo *CSI =
13380b57cec5SDimitry Andric             dyn_cast<CapturingScopeInfo>(FunctionScopes[idx])) {
13390b57cec5SDimitry Andric       if (CSI->CXXThisCaptureIndex != 0) {
13400b57cec5SDimitry Andric         // 'this' is already being captured; there isn't anything more to do.
13410b57cec5SDimitry Andric         CSI->Captures[CSI->CXXThisCaptureIndex - 1].markUsed(BuildAndDiagnose);
13420b57cec5SDimitry Andric         break;
13430b57cec5SDimitry Andric       }
13440b57cec5SDimitry Andric       LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI);
13450b57cec5SDimitry Andric       if (LSI && isGenericLambdaCallOperatorSpecialization(LSI->CallOperator)) {
13460b57cec5SDimitry Andric         // This context can't implicitly capture 'this'; fail out.
1347fe6060f1SDimitry Andric         if (BuildAndDiagnose) {
13485f757f3fSDimitry Andric           LSI->CallOperator->setInvalidDecl();
13490b57cec5SDimitry Andric           Diag(Loc, diag::err_this_capture)
13500b57cec5SDimitry Andric               << (Explicit && idx == MaxFunctionScopesIndex);
1351fe6060f1SDimitry Andric           if (!Explicit)
1352fe6060f1SDimitry Andric             buildLambdaThisCaptureFixit(*this, LSI);
1353fe6060f1SDimitry Andric         }
13540b57cec5SDimitry Andric         return true;
13550b57cec5SDimitry Andric       }
13560b57cec5SDimitry Andric       if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref ||
13570b57cec5SDimitry Andric           CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval ||
13580b57cec5SDimitry Andric           CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block ||
13590b57cec5SDimitry Andric           CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_CapturedRegion ||
13600b57cec5SDimitry Andric           (Explicit && idx == MaxFunctionScopesIndex)) {
13610b57cec5SDimitry Andric         // Regarding (Explicit && idx == MaxFunctionScopesIndex): only the first
13620b57cec5SDimitry Andric         // iteration through can be an explicit capture, all enclosing closures,
13630b57cec5SDimitry Andric         // if any, must perform implicit captures.
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric         // This closure can capture 'this'; continue looking upwards.
13660b57cec5SDimitry Andric         NumCapturingClosures++;
13670b57cec5SDimitry Andric         continue;
13680b57cec5SDimitry Andric       }
13690b57cec5SDimitry Andric       // This context can't implicitly capture 'this'; fail out.
13705f757f3fSDimitry Andric       if (BuildAndDiagnose) {
13715f757f3fSDimitry Andric         LSI->CallOperator->setInvalidDecl();
13720b57cec5SDimitry Andric         Diag(Loc, diag::err_this_capture)
13730b57cec5SDimitry Andric             << (Explicit && idx == MaxFunctionScopesIndex);
13745f757f3fSDimitry Andric       }
1375fe6060f1SDimitry Andric       if (!Explicit)
1376fe6060f1SDimitry Andric         buildLambdaThisCaptureFixit(*this, LSI);
13770b57cec5SDimitry Andric       return true;
13780b57cec5SDimitry Andric     }
13790b57cec5SDimitry Andric     break;
13800b57cec5SDimitry Andric   }
13810b57cec5SDimitry Andric   if (!BuildAndDiagnose) return false;
13820b57cec5SDimitry Andric 
13830b57cec5SDimitry Andric   // If we got here, then the closure at MaxFunctionScopesIndex on the
13840b57cec5SDimitry Andric   // FunctionScopes stack, can capture the *enclosing object*, so capture it
13850b57cec5SDimitry Andric   // (including implicit by-reference captures in any enclosing closures).
13860b57cec5SDimitry Andric 
13870b57cec5SDimitry Andric   // In the loop below, respect the ByCopy flag only for the closure requesting
13880b57cec5SDimitry Andric   // the capture (i.e. first iteration through the loop below).  Ignore it for
13890b57cec5SDimitry Andric   // all enclosing closure's up to NumCapturingClosures (since they must be
13900b57cec5SDimitry Andric   // implicitly capturing the *enclosing  object* by reference (see loop
13910b57cec5SDimitry Andric   // above)).
13920b57cec5SDimitry Andric   assert((!ByCopy ||
13930eae32dcSDimitry Andric           isa<LambdaScopeInfo>(FunctionScopes[MaxFunctionScopesIndex])) &&
13940b57cec5SDimitry Andric          "Only a lambda can capture the enclosing object (referred to by "
13950b57cec5SDimitry Andric          "*this) by copy");
13960b57cec5SDimitry Andric   QualType ThisTy = getCurrentThisType();
13970b57cec5SDimitry Andric   for (int idx = MaxFunctionScopesIndex; NumCapturingClosures;
13980b57cec5SDimitry Andric        --idx, --NumCapturingClosures) {
13990b57cec5SDimitry Andric     CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
14000b57cec5SDimitry Andric 
14010b57cec5SDimitry Andric     // The type of the corresponding data member (not a 'this' pointer if 'by
14020b57cec5SDimitry Andric     // copy').
140306c3fb27SDimitry Andric     QualType CaptureType = ByCopy ? ThisTy->getPointeeType() : ThisTy;
14040b57cec5SDimitry Andric 
14050b57cec5SDimitry Andric     bool isNested = NumCapturingClosures > 1;
14060b57cec5SDimitry Andric     CSI->addThisCapture(isNested, Loc, CaptureType, ByCopy);
14070b57cec5SDimitry Andric   }
14080b57cec5SDimitry Andric   return false;
14090b57cec5SDimitry Andric }
14100b57cec5SDimitry Andric 
ActOnCXXThis(SourceLocation Loc)14110b57cec5SDimitry Andric ExprResult Sema::ActOnCXXThis(SourceLocation Loc) {
14120b57cec5SDimitry Andric   /// C++ 9.3.2: In the body of a non-static member function, the keyword this
14130b57cec5SDimitry Andric   /// is a non-lvalue expression whose value is the address of the object for
14140b57cec5SDimitry Andric   /// which the function is called.
14150b57cec5SDimitry Andric   QualType ThisTy = getCurrentThisType();
14165f757f3fSDimitry Andric 
14175f757f3fSDimitry Andric   if (ThisTy.isNull()) {
14185f757f3fSDimitry Andric     DeclContext *DC = getFunctionLevelDeclContext();
14195f757f3fSDimitry Andric 
14205f757f3fSDimitry Andric     if (const auto *Method = dyn_cast<CXXMethodDecl>(DC);
14215f757f3fSDimitry Andric         Method && Method->isExplicitObjectMemberFunction()) {
14225f757f3fSDimitry Andric       return Diag(Loc, diag::err_invalid_this_use) << 1;
14235f757f3fSDimitry Andric     }
14245f757f3fSDimitry Andric 
14255f757f3fSDimitry Andric     if (isLambdaCallWithExplicitObjectParameter(CurContext))
14265f757f3fSDimitry Andric       return Diag(Loc, diag::err_invalid_this_use) << 1;
14275f757f3fSDimitry Andric 
14285f757f3fSDimitry Andric     return Diag(Loc, diag::err_invalid_this_use) << 0;
14295f757f3fSDimitry Andric   }
14305f757f3fSDimitry Andric 
14310b57cec5SDimitry Andric   return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false);
14320b57cec5SDimitry Andric }
14330b57cec5SDimitry Andric 
BuildCXXThisExpr(SourceLocation Loc,QualType Type,bool IsImplicit)14340b57cec5SDimitry Andric Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type,
14350b57cec5SDimitry Andric                              bool IsImplicit) {
14365f757f3fSDimitry Andric   auto *This = CXXThisExpr::Create(Context, Loc, Type, IsImplicit);
14370b57cec5SDimitry Andric   MarkThisReferenced(This);
14380b57cec5SDimitry Andric   return This;
14390b57cec5SDimitry Andric }
14400b57cec5SDimitry Andric 
MarkThisReferenced(CXXThisExpr * This)14410b57cec5SDimitry Andric void Sema::MarkThisReferenced(CXXThisExpr *This) {
14420b57cec5SDimitry Andric   CheckCXXThisCapture(This->getExprLoc());
14430b57cec5SDimitry Andric }
14440b57cec5SDimitry Andric 
isThisOutsideMemberFunctionBody(QualType BaseType)14450b57cec5SDimitry Andric bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) {
14460b57cec5SDimitry Andric   // If we're outside the body of a member function, then we'll have a specified
14470b57cec5SDimitry Andric   // type for 'this'.
14480b57cec5SDimitry Andric   if (CXXThisTypeOverride.isNull())
14490b57cec5SDimitry Andric     return false;
14500b57cec5SDimitry Andric 
14510b57cec5SDimitry Andric   // Determine whether we're looking into a class that's currently being
14520b57cec5SDimitry Andric   // defined.
14530b57cec5SDimitry Andric   CXXRecordDecl *Class = BaseType->getAsCXXRecordDecl();
14540b57cec5SDimitry Andric   return Class && Class->isBeingDefined();
14550b57cec5SDimitry Andric }
14560b57cec5SDimitry Andric 
14570b57cec5SDimitry Andric /// Parse construction of a specified type.
14580b57cec5SDimitry Andric /// Can be interpreted either as function-style casting ("int(x)")
14590b57cec5SDimitry Andric /// or class type construction ("ClassType(x,y,z)")
14600b57cec5SDimitry Andric /// or creation of a value-initialized type ("int()").
14610b57cec5SDimitry Andric ExprResult
ActOnCXXTypeConstructExpr(ParsedType TypeRep,SourceLocation LParenOrBraceLoc,MultiExprArg exprs,SourceLocation RParenOrBraceLoc,bool ListInitialization)14620b57cec5SDimitry Andric Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
14630b57cec5SDimitry Andric                                 SourceLocation LParenOrBraceLoc,
14640b57cec5SDimitry Andric                                 MultiExprArg exprs,
14650b57cec5SDimitry Andric                                 SourceLocation RParenOrBraceLoc,
14660b57cec5SDimitry Andric                                 bool ListInitialization) {
14670b57cec5SDimitry Andric   if (!TypeRep)
14680b57cec5SDimitry Andric     return ExprError();
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric   TypeSourceInfo *TInfo;
14710b57cec5SDimitry Andric   QualType Ty = GetTypeFromParser(TypeRep, &TInfo);
14720b57cec5SDimitry Andric   if (!TInfo)
14730b57cec5SDimitry Andric     TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation());
14740b57cec5SDimitry Andric 
14750b57cec5SDimitry Andric   auto Result = BuildCXXTypeConstructExpr(TInfo, LParenOrBraceLoc, exprs,
14760b57cec5SDimitry Andric                                           RParenOrBraceLoc, ListInitialization);
14770b57cec5SDimitry Andric   // Avoid creating a non-type-dependent expression that contains typos.
14780b57cec5SDimitry Andric   // Non-type-dependent expressions are liable to be discarded without
14790b57cec5SDimitry Andric   // checking for embedded typos.
14800b57cec5SDimitry Andric   if (!Result.isInvalid() && Result.get()->isInstantiationDependent() &&
14810b57cec5SDimitry Andric       !Result.get()->isTypeDependent())
14820b57cec5SDimitry Andric     Result = CorrectDelayedTyposInExpr(Result.get());
1483e8d8bef9SDimitry Andric   else if (Result.isInvalid())
1484e8d8bef9SDimitry Andric     Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(),
1485e8d8bef9SDimitry Andric                                 RParenOrBraceLoc, exprs, Ty);
14860b57cec5SDimitry Andric   return Result;
14870b57cec5SDimitry Andric }
14880b57cec5SDimitry Andric 
14890b57cec5SDimitry Andric ExprResult
BuildCXXTypeConstructExpr(TypeSourceInfo * TInfo,SourceLocation LParenOrBraceLoc,MultiExprArg Exprs,SourceLocation RParenOrBraceLoc,bool ListInitialization)14900b57cec5SDimitry Andric Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
14910b57cec5SDimitry Andric                                 SourceLocation LParenOrBraceLoc,
14920b57cec5SDimitry Andric                                 MultiExprArg Exprs,
14930b57cec5SDimitry Andric                                 SourceLocation RParenOrBraceLoc,
14940b57cec5SDimitry Andric                                 bool ListInitialization) {
14950b57cec5SDimitry Andric   QualType Ty = TInfo->getType();
14960b57cec5SDimitry Andric   SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
14970b57cec5SDimitry Andric 
1498bdd1243dSDimitry Andric   assert((!ListInitialization || Exprs.size() == 1) &&
1499bdd1243dSDimitry Andric          "List initialization must have exactly one expression.");
15000b57cec5SDimitry Andric   SourceRange FullRange = SourceRange(TyBeginLoc, RParenOrBraceLoc);
15010b57cec5SDimitry Andric 
1502349cc55cSDimitry Andric   InitializedEntity Entity =
1503349cc55cSDimitry Andric       InitializedEntity::InitializeTemporary(Context, TInfo);
15040b57cec5SDimitry Andric   InitializationKind Kind =
15050b57cec5SDimitry Andric       Exprs.size()
15060b57cec5SDimitry Andric           ? ListInitialization
15070b57cec5SDimitry Andric                 ? InitializationKind::CreateDirectList(
15080b57cec5SDimitry Andric                       TyBeginLoc, LParenOrBraceLoc, RParenOrBraceLoc)
15090b57cec5SDimitry Andric                 : InitializationKind::CreateDirect(TyBeginLoc, LParenOrBraceLoc,
15100b57cec5SDimitry Andric                                                    RParenOrBraceLoc)
15110b57cec5SDimitry Andric           : InitializationKind::CreateValue(TyBeginLoc, LParenOrBraceLoc,
15120b57cec5SDimitry Andric                                             RParenOrBraceLoc);
15130b57cec5SDimitry Andric 
151406c3fb27SDimitry Andric   // C++17 [expr.type.conv]p1:
15150b57cec5SDimitry Andric   //   If the type is a placeholder for a deduced class type, [...perform class
15160b57cec5SDimitry Andric   //   template argument deduction...]
151706c3fb27SDimitry Andric   // C++23:
151881ad6265SDimitry Andric   //   Otherwise, if the type contains a placeholder type, it is replaced by the
151981ad6265SDimitry Andric   //   type determined by placeholder type deduction.
15200b57cec5SDimitry Andric   DeducedType *Deduced = Ty->getContainedDeducedType();
15211ac55f4cSDimitry Andric   if (Deduced && !Deduced->isDeduced() &&
15221ac55f4cSDimitry Andric       isa<DeducedTemplateSpecializationType>(Deduced)) {
15230b57cec5SDimitry Andric     Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity,
15240b57cec5SDimitry Andric                                                      Kind, Exprs);
15250b57cec5SDimitry Andric     if (Ty.isNull())
15260b57cec5SDimitry Andric       return ExprError();
15270b57cec5SDimitry Andric     Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
15281ac55f4cSDimitry Andric   } else if (Deduced && !Deduced->isDeduced()) {
152981ad6265SDimitry Andric     MultiExprArg Inits = Exprs;
153081ad6265SDimitry Andric     if (ListInitialization) {
153181ad6265SDimitry Andric       auto *ILE = cast<InitListExpr>(Exprs[0]);
153281ad6265SDimitry Andric       Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits());
153381ad6265SDimitry Andric     }
153481ad6265SDimitry Andric 
153581ad6265SDimitry Andric     if (Inits.empty())
153681ad6265SDimitry Andric       return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_init_no_expression)
153781ad6265SDimitry Andric                        << Ty << FullRange);
153881ad6265SDimitry Andric     if (Inits.size() > 1) {
153981ad6265SDimitry Andric       Expr *FirstBad = Inits[1];
154081ad6265SDimitry Andric       return ExprError(Diag(FirstBad->getBeginLoc(),
154181ad6265SDimitry Andric                             diag::err_auto_expr_init_multiple_expressions)
154281ad6265SDimitry Andric                        << Ty << FullRange);
154381ad6265SDimitry Andric     }
154406c3fb27SDimitry Andric     if (getLangOpts().CPlusPlus23) {
154581ad6265SDimitry Andric       if (Ty->getAs<AutoType>())
154681ad6265SDimitry Andric         Diag(TyBeginLoc, diag::warn_cxx20_compat_auto_expr) << FullRange;
154781ad6265SDimitry Andric     }
154881ad6265SDimitry Andric     Expr *Deduce = Inits[0];
154981ad6265SDimitry Andric     if (isa<InitListExpr>(Deduce))
155081ad6265SDimitry Andric       return ExprError(
155181ad6265SDimitry Andric           Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces)
155281ad6265SDimitry Andric           << ListInitialization << Ty << FullRange);
155381ad6265SDimitry Andric     QualType DeducedType;
1554bdd1243dSDimitry Andric     TemplateDeductionInfo Info(Deduce->getExprLoc());
1555bdd1243dSDimitry Andric     TemplateDeductionResult Result =
1556bdd1243dSDimitry Andric         DeduceAutoType(TInfo->getTypeLoc(), Deduce, DeducedType, Info);
1557bdd1243dSDimitry Andric     if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed)
155881ad6265SDimitry Andric       return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_deduction_failure)
155981ad6265SDimitry Andric                        << Ty << Deduce->getType() << FullRange
156081ad6265SDimitry Andric                        << Deduce->getSourceRange());
1561bdd1243dSDimitry Andric     if (DeducedType.isNull()) {
1562bdd1243dSDimitry Andric       assert(Result == TDK_AlreadyDiagnosed);
156381ad6265SDimitry Andric       return ExprError();
1564bdd1243dSDimitry Andric     }
156581ad6265SDimitry Andric 
156681ad6265SDimitry Andric     Ty = DeducedType;
156781ad6265SDimitry Andric     Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
15680b57cec5SDimitry Andric   }
15690b57cec5SDimitry Andric 
157006c3fb27SDimitry Andric   if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs))
157106c3fb27SDimitry Andric     return CXXUnresolvedConstructExpr::Create(
157206c3fb27SDimitry Andric         Context, Ty.getNonReferenceType(), TInfo, LParenOrBraceLoc, Exprs,
157306c3fb27SDimitry Andric         RParenOrBraceLoc, ListInitialization);
1574e8d8bef9SDimitry Andric 
15750b57cec5SDimitry Andric   // C++ [expr.type.conv]p1:
15760b57cec5SDimitry Andric   // If the expression list is a parenthesized single expression, the type
15770b57cec5SDimitry Andric   // conversion expression is equivalent (in definedness, and if defined in
15780b57cec5SDimitry Andric   // meaning) to the corresponding cast expression.
15790b57cec5SDimitry Andric   if (Exprs.size() == 1 && !ListInitialization &&
15800b57cec5SDimitry Andric       !isa<InitListExpr>(Exprs[0])) {
15810b57cec5SDimitry Andric     Expr *Arg = Exprs[0];
15820b57cec5SDimitry Andric     return BuildCXXFunctionalCastExpr(TInfo, Ty, LParenOrBraceLoc, Arg,
15830b57cec5SDimitry Andric                                       RParenOrBraceLoc);
15840b57cec5SDimitry Andric   }
15850b57cec5SDimitry Andric 
15860b57cec5SDimitry Andric   //   For an expression of the form T(), T shall not be an array type.
15870b57cec5SDimitry Andric   QualType ElemTy = Ty;
15880b57cec5SDimitry Andric   if (Ty->isArrayType()) {
15890b57cec5SDimitry Andric     if (!ListInitialization)
15900b57cec5SDimitry Andric       return ExprError(Diag(TyBeginLoc, diag::err_value_init_for_array_type)
15910b57cec5SDimitry Andric                          << FullRange);
15920b57cec5SDimitry Andric     ElemTy = Context.getBaseElementType(Ty);
15930b57cec5SDimitry Andric   }
15940b57cec5SDimitry Andric 
15955e801ac6SDimitry Andric   // Only construct objects with object types.
15964824e7fdSDimitry Andric   // The standard doesn't explicitly forbid function types here, but that's an
15974824e7fdSDimitry Andric   // obvious oversight, as there's no way to dynamically construct a function
15984824e7fdSDimitry Andric   // in general.
15990b57cec5SDimitry Andric   if (Ty->isFunctionType())
16000b57cec5SDimitry Andric     return ExprError(Diag(TyBeginLoc, diag::err_init_for_function_type)
16010b57cec5SDimitry Andric                        << Ty << FullRange);
16020b57cec5SDimitry Andric 
16030b57cec5SDimitry Andric   // C++17 [expr.type.conv]p2:
16040b57cec5SDimitry Andric   //   If the type is cv void and the initializer is (), the expression is a
16050b57cec5SDimitry Andric   //   prvalue of the specified type that performs no initialization.
16060b57cec5SDimitry Andric   if (!Ty->isVoidType() &&
16070b57cec5SDimitry Andric       RequireCompleteType(TyBeginLoc, ElemTy,
16080b57cec5SDimitry Andric                           diag::err_invalid_incomplete_type_use, FullRange))
16090b57cec5SDimitry Andric     return ExprError();
16100b57cec5SDimitry Andric 
16110b57cec5SDimitry Andric   //   Otherwise, the expression is a prvalue of the specified type whose
16120b57cec5SDimitry Andric   //   result object is direct-initialized (11.6) with the initializer.
16130b57cec5SDimitry Andric   InitializationSequence InitSeq(*this, Entity, Kind, Exprs);
16140b57cec5SDimitry Andric   ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Exprs);
16150b57cec5SDimitry Andric 
16160b57cec5SDimitry Andric   if (Result.isInvalid())
16170b57cec5SDimitry Andric     return Result;
16180b57cec5SDimitry Andric 
16190b57cec5SDimitry Andric   Expr *Inner = Result.get();
16200b57cec5SDimitry Andric   if (CXXBindTemporaryExpr *BTE = dyn_cast_or_null<CXXBindTemporaryExpr>(Inner))
16210b57cec5SDimitry Andric     Inner = BTE->getSubExpr();
162206c3fb27SDimitry Andric   if (auto *CE = dyn_cast<ConstantExpr>(Inner);
162306c3fb27SDimitry Andric       CE && CE->isImmediateInvocation())
162406c3fb27SDimitry Andric     Inner = CE->getSubExpr();
16250b57cec5SDimitry Andric   if (!isa<CXXTemporaryObjectExpr>(Inner) &&
16260b57cec5SDimitry Andric       !isa<CXXScalarValueInitExpr>(Inner)) {
16270b57cec5SDimitry Andric     // If we created a CXXTemporaryObjectExpr, that node also represents the
16280b57cec5SDimitry Andric     // functional cast. Otherwise, create an explicit cast to represent
16290b57cec5SDimitry Andric     // the syntactic form of a functional-style cast that was used here.
16300b57cec5SDimitry Andric     //
16310b57cec5SDimitry Andric     // FIXME: Creating a CXXFunctionalCastExpr around a CXXConstructExpr
16320b57cec5SDimitry Andric     // would give a more consistent AST representation than using a
16330b57cec5SDimitry Andric     // CXXTemporaryObjectExpr. It's also weird that the functional cast
16340b57cec5SDimitry Andric     // is sometimes handled by initialization and sometimes not.
16350b57cec5SDimitry Andric     QualType ResultType = Result.get()->getType();
16360b57cec5SDimitry Andric     SourceRange Locs = ListInitialization
16370b57cec5SDimitry Andric                            ? SourceRange()
16380b57cec5SDimitry Andric                            : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
16390b57cec5SDimitry Andric     Result = CXXFunctionalCastExpr::Create(
16400b57cec5SDimitry Andric         Context, ResultType, Expr::getValueKindForType(Ty), TInfo, CK_NoOp,
1641e8d8bef9SDimitry Andric         Result.get(), /*Path=*/nullptr, CurFPFeatureOverrides(),
1642e8d8bef9SDimitry Andric         Locs.getBegin(), Locs.getEnd());
16430b57cec5SDimitry Andric   }
16440b57cec5SDimitry Andric 
16450b57cec5SDimitry Andric   return Result;
16460b57cec5SDimitry Andric }
16470b57cec5SDimitry Andric 
isUsualDeallocationFunction(const CXXMethodDecl * Method)16480b57cec5SDimitry Andric bool Sema::isUsualDeallocationFunction(const CXXMethodDecl *Method) {
16490b57cec5SDimitry Andric   // [CUDA] Ignore this function, if we can't call it.
165081ad6265SDimitry Andric   const FunctionDecl *Caller = getCurFunctionDecl(/*AllowLambda=*/true);
1651e8d8bef9SDimitry Andric   if (getLangOpts().CUDA) {
1652e8d8bef9SDimitry Andric     auto CallPreference = IdentifyCUDAPreference(Caller, Method);
1653e8d8bef9SDimitry Andric     // If it's not callable at all, it's not the right function.
1654e8d8bef9SDimitry Andric     if (CallPreference < CFP_WrongSide)
16550b57cec5SDimitry Andric       return false;
1656e8d8bef9SDimitry Andric     if (CallPreference == CFP_WrongSide) {
1657e8d8bef9SDimitry Andric       // Maybe. We have to check if there are better alternatives.
1658e8d8bef9SDimitry Andric       DeclContext::lookup_result R =
1659e8d8bef9SDimitry Andric           Method->getDeclContext()->lookup(Method->getDeclName());
1660e8d8bef9SDimitry Andric       for (const auto *D : R) {
1661e8d8bef9SDimitry Andric         if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1662e8d8bef9SDimitry Andric           if (IdentifyCUDAPreference(Caller, FD) > CFP_WrongSide)
1663e8d8bef9SDimitry Andric             return false;
1664e8d8bef9SDimitry Andric         }
1665e8d8bef9SDimitry Andric       }
1666e8d8bef9SDimitry Andric       // We've found no better variants.
1667e8d8bef9SDimitry Andric     }
1668e8d8bef9SDimitry Andric   }
16690b57cec5SDimitry Andric 
16700b57cec5SDimitry Andric   SmallVector<const FunctionDecl*, 4> PreventedBy;
16710b57cec5SDimitry Andric   bool Result = Method->isUsualDeallocationFunction(PreventedBy);
16720b57cec5SDimitry Andric 
16730b57cec5SDimitry Andric   if (Result || !getLangOpts().CUDA || PreventedBy.empty())
16740b57cec5SDimitry Andric     return Result;
16750b57cec5SDimitry Andric 
16760b57cec5SDimitry Andric   // In case of CUDA, return true if none of the 1-argument deallocator
16770b57cec5SDimitry Andric   // functions are actually callable.
16780b57cec5SDimitry Andric   return llvm::none_of(PreventedBy, [&](const FunctionDecl *FD) {
16790b57cec5SDimitry Andric     assert(FD->getNumParams() == 1 &&
16800b57cec5SDimitry Andric            "Only single-operand functions should be in PreventedBy");
16810b57cec5SDimitry Andric     return IdentifyCUDAPreference(Caller, FD) >= CFP_HostDevice;
16820b57cec5SDimitry Andric   });
16830b57cec5SDimitry Andric }
16840b57cec5SDimitry Andric 
16850b57cec5SDimitry Andric /// Determine whether the given function is a non-placement
16860b57cec5SDimitry Andric /// deallocation function.
isNonPlacementDeallocationFunction(Sema & S,FunctionDecl * FD)16870b57cec5SDimitry Andric static bool isNonPlacementDeallocationFunction(Sema &S, FunctionDecl *FD) {
16880b57cec5SDimitry Andric   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD))
16890b57cec5SDimitry Andric     return S.isUsualDeallocationFunction(Method);
16900b57cec5SDimitry Andric 
16910b57cec5SDimitry Andric   if (FD->getOverloadedOperator() != OO_Delete &&
16920b57cec5SDimitry Andric       FD->getOverloadedOperator() != OO_Array_Delete)
16930b57cec5SDimitry Andric     return false;
16940b57cec5SDimitry Andric 
16950b57cec5SDimitry Andric   unsigned UsualParams = 1;
16960b57cec5SDimitry Andric 
16970b57cec5SDimitry Andric   if (S.getLangOpts().SizedDeallocation && UsualParams < FD->getNumParams() &&
16980b57cec5SDimitry Andric       S.Context.hasSameUnqualifiedType(
16990b57cec5SDimitry Andric           FD->getParamDecl(UsualParams)->getType(),
17000b57cec5SDimitry Andric           S.Context.getSizeType()))
17010b57cec5SDimitry Andric     ++UsualParams;
17020b57cec5SDimitry Andric 
17030b57cec5SDimitry Andric   if (S.getLangOpts().AlignedAllocation && UsualParams < FD->getNumParams() &&
17040b57cec5SDimitry Andric       S.Context.hasSameUnqualifiedType(
17050b57cec5SDimitry Andric           FD->getParamDecl(UsualParams)->getType(),
17060b57cec5SDimitry Andric           S.Context.getTypeDeclType(S.getStdAlignValT())))
17070b57cec5SDimitry Andric     ++UsualParams;
17080b57cec5SDimitry Andric 
17090b57cec5SDimitry Andric   return UsualParams == FD->getNumParams();
17100b57cec5SDimitry Andric }
17110b57cec5SDimitry Andric 
17120b57cec5SDimitry Andric namespace {
17130b57cec5SDimitry Andric   struct UsualDeallocFnInfo {
UsualDeallocFnInfo__anon4c809b4f0a11::UsualDeallocFnInfo17140b57cec5SDimitry Andric     UsualDeallocFnInfo() : Found(), FD(nullptr) {}
UsualDeallocFnInfo__anon4c809b4f0a11::UsualDeallocFnInfo17150b57cec5SDimitry Andric     UsualDeallocFnInfo(Sema &S, DeclAccessPair Found)
17160b57cec5SDimitry Andric         : Found(Found), FD(dyn_cast<FunctionDecl>(Found->getUnderlyingDecl())),
17170b57cec5SDimitry Andric           Destroying(false), HasSizeT(false), HasAlignValT(false),
17180b57cec5SDimitry Andric           CUDAPref(Sema::CFP_Native) {
17190b57cec5SDimitry Andric       // A function template declaration is never a usual deallocation function.
17200b57cec5SDimitry Andric       if (!FD)
17210b57cec5SDimitry Andric         return;
17220b57cec5SDimitry Andric       unsigned NumBaseParams = 1;
17230b57cec5SDimitry Andric       if (FD->isDestroyingOperatorDelete()) {
17240b57cec5SDimitry Andric         Destroying = true;
17250b57cec5SDimitry Andric         ++NumBaseParams;
17260b57cec5SDimitry Andric       }
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric       if (NumBaseParams < FD->getNumParams() &&
17290b57cec5SDimitry Andric           S.Context.hasSameUnqualifiedType(
17300b57cec5SDimitry Andric               FD->getParamDecl(NumBaseParams)->getType(),
17310b57cec5SDimitry Andric               S.Context.getSizeType())) {
17320b57cec5SDimitry Andric         ++NumBaseParams;
17330b57cec5SDimitry Andric         HasSizeT = true;
17340b57cec5SDimitry Andric       }
17350b57cec5SDimitry Andric 
17360b57cec5SDimitry Andric       if (NumBaseParams < FD->getNumParams() &&
17370b57cec5SDimitry Andric           FD->getParamDecl(NumBaseParams)->getType()->isAlignValT()) {
17380b57cec5SDimitry Andric         ++NumBaseParams;
17390b57cec5SDimitry Andric         HasAlignValT = true;
17400b57cec5SDimitry Andric       }
17410b57cec5SDimitry Andric 
17420b57cec5SDimitry Andric       // In CUDA, determine how much we'd like / dislike to call this.
17430b57cec5SDimitry Andric       if (S.getLangOpts().CUDA)
17445f757f3fSDimitry Andric         CUDAPref = S.IdentifyCUDAPreference(
17455f757f3fSDimitry Andric             S.getCurFunctionDecl(/*AllowLambda=*/true), FD);
17460b57cec5SDimitry Andric     }
17470b57cec5SDimitry Andric 
operator bool__anon4c809b4f0a11::UsualDeallocFnInfo17480b57cec5SDimitry Andric     explicit operator bool() const { return FD; }
17490b57cec5SDimitry Andric 
isBetterThan__anon4c809b4f0a11::UsualDeallocFnInfo17500b57cec5SDimitry Andric     bool isBetterThan(const UsualDeallocFnInfo &Other, bool WantSize,
17510b57cec5SDimitry Andric                       bool WantAlign) const {
17520b57cec5SDimitry Andric       // C++ P0722:
17530b57cec5SDimitry Andric       //   A destroying operator delete is preferred over a non-destroying
17540b57cec5SDimitry Andric       //   operator delete.
17550b57cec5SDimitry Andric       if (Destroying != Other.Destroying)
17560b57cec5SDimitry Andric         return Destroying;
17570b57cec5SDimitry Andric 
17580b57cec5SDimitry Andric       // C++17 [expr.delete]p10:
17590b57cec5SDimitry Andric       //   If the type has new-extended alignment, a function with a parameter
17600b57cec5SDimitry Andric       //   of type std::align_val_t is preferred; otherwise a function without
17610b57cec5SDimitry Andric       //   such a parameter is preferred
17620b57cec5SDimitry Andric       if (HasAlignValT != Other.HasAlignValT)
17630b57cec5SDimitry Andric         return HasAlignValT == WantAlign;
17640b57cec5SDimitry Andric 
17650b57cec5SDimitry Andric       if (HasSizeT != Other.HasSizeT)
17660b57cec5SDimitry Andric         return HasSizeT == WantSize;
17670b57cec5SDimitry Andric 
17680b57cec5SDimitry Andric       // Use CUDA call preference as a tiebreaker.
17690b57cec5SDimitry Andric       return CUDAPref > Other.CUDAPref;
17700b57cec5SDimitry Andric     }
17710b57cec5SDimitry Andric 
17720b57cec5SDimitry Andric     DeclAccessPair Found;
17730b57cec5SDimitry Andric     FunctionDecl *FD;
17740b57cec5SDimitry Andric     bool Destroying, HasSizeT, HasAlignValT;
17750b57cec5SDimitry Andric     Sema::CUDAFunctionPreference CUDAPref;
17760b57cec5SDimitry Andric   };
17770b57cec5SDimitry Andric }
17780b57cec5SDimitry Andric 
17790b57cec5SDimitry Andric /// Determine whether a type has new-extended alignment. This may be called when
17800b57cec5SDimitry Andric /// the type is incomplete (for a delete-expression with an incomplete pointee
17810b57cec5SDimitry Andric /// type), in which case it will conservatively return false if the alignment is
17820b57cec5SDimitry Andric /// not known.
hasNewExtendedAlignment(Sema & S,QualType AllocType)17830b57cec5SDimitry Andric static bool hasNewExtendedAlignment(Sema &S, QualType AllocType) {
17840b57cec5SDimitry Andric   return S.getLangOpts().AlignedAllocation &&
17850b57cec5SDimitry Andric          S.getASTContext().getTypeAlignIfKnown(AllocType) >
17860b57cec5SDimitry Andric              S.getASTContext().getTargetInfo().getNewAlign();
17870b57cec5SDimitry Andric }
17880b57cec5SDimitry Andric 
17890b57cec5SDimitry Andric /// Select the correct "usual" deallocation function to use from a selection of
17900b57cec5SDimitry Andric /// deallocation functions (either global or class-scope).
resolveDeallocationOverload(Sema & S,LookupResult & R,bool WantSize,bool WantAlign,llvm::SmallVectorImpl<UsualDeallocFnInfo> * BestFns=nullptr)17910b57cec5SDimitry Andric static UsualDeallocFnInfo resolveDeallocationOverload(
17920b57cec5SDimitry Andric     Sema &S, LookupResult &R, bool WantSize, bool WantAlign,
17930b57cec5SDimitry Andric     llvm::SmallVectorImpl<UsualDeallocFnInfo> *BestFns = nullptr) {
17940b57cec5SDimitry Andric   UsualDeallocFnInfo Best;
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric   for (auto I = R.begin(), E = R.end(); I != E; ++I) {
17970b57cec5SDimitry Andric     UsualDeallocFnInfo Info(S, I.getPair());
17980b57cec5SDimitry Andric     if (!Info || !isNonPlacementDeallocationFunction(S, Info.FD) ||
17990b57cec5SDimitry Andric         Info.CUDAPref == Sema::CFP_Never)
18000b57cec5SDimitry Andric       continue;
18010b57cec5SDimitry Andric 
18020b57cec5SDimitry Andric     if (!Best) {
18030b57cec5SDimitry Andric       Best = Info;
18040b57cec5SDimitry Andric       if (BestFns)
18050b57cec5SDimitry Andric         BestFns->push_back(Info);
18060b57cec5SDimitry Andric       continue;
18070b57cec5SDimitry Andric     }
18080b57cec5SDimitry Andric 
18090b57cec5SDimitry Andric     if (Best.isBetterThan(Info, WantSize, WantAlign))
18100b57cec5SDimitry Andric       continue;
18110b57cec5SDimitry Andric 
18120b57cec5SDimitry Andric     //   If more than one preferred function is found, all non-preferred
18130b57cec5SDimitry Andric     //   functions are eliminated from further consideration.
18140b57cec5SDimitry Andric     if (BestFns && Info.isBetterThan(Best, WantSize, WantAlign))
18150b57cec5SDimitry Andric       BestFns->clear();
18160b57cec5SDimitry Andric 
18170b57cec5SDimitry Andric     Best = Info;
18180b57cec5SDimitry Andric     if (BestFns)
18190b57cec5SDimitry Andric       BestFns->push_back(Info);
18200b57cec5SDimitry Andric   }
18210b57cec5SDimitry Andric 
18220b57cec5SDimitry Andric   return Best;
18230b57cec5SDimitry Andric }
18240b57cec5SDimitry Andric 
18250b57cec5SDimitry Andric /// Determine whether a given type is a class for which 'delete[]' would call
18260b57cec5SDimitry Andric /// a member 'operator delete[]' with a 'size_t' parameter. This implies that
18270b57cec5SDimitry Andric /// we need to store the array size (even if the type is
18280b57cec5SDimitry Andric /// trivially-destructible).
doesUsualArrayDeleteWantSize(Sema & S,SourceLocation loc,QualType allocType)18290b57cec5SDimitry Andric static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc,
18300b57cec5SDimitry Andric                                          QualType allocType) {
18310b57cec5SDimitry Andric   const RecordType *record =
18320b57cec5SDimitry Andric     allocType->getBaseElementTypeUnsafe()->getAs<RecordType>();
18330b57cec5SDimitry Andric   if (!record) return false;
18340b57cec5SDimitry Andric 
18350b57cec5SDimitry Andric   // Try to find an operator delete[] in class scope.
18360b57cec5SDimitry Andric 
18370b57cec5SDimitry Andric   DeclarationName deleteName =
18380b57cec5SDimitry Andric     S.Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
18390b57cec5SDimitry Andric   LookupResult ops(S, deleteName, loc, Sema::LookupOrdinaryName);
18400b57cec5SDimitry Andric   S.LookupQualifiedName(ops, record->getDecl());
18410b57cec5SDimitry Andric 
18420b57cec5SDimitry Andric   // We're just doing this for information.
18430b57cec5SDimitry Andric   ops.suppressDiagnostics();
18440b57cec5SDimitry Andric 
18450b57cec5SDimitry Andric   // Very likely: there's no operator delete[].
18460b57cec5SDimitry Andric   if (ops.empty()) return false;
18470b57cec5SDimitry Andric 
18480b57cec5SDimitry Andric   // If it's ambiguous, it should be illegal to call operator delete[]
18490b57cec5SDimitry Andric   // on this thing, so it doesn't matter if we allocate extra space or not.
18500b57cec5SDimitry Andric   if (ops.isAmbiguous()) return false;
18510b57cec5SDimitry Andric 
18520b57cec5SDimitry Andric   // C++17 [expr.delete]p10:
18530b57cec5SDimitry Andric   //   If the deallocation functions have class scope, the one without a
18540b57cec5SDimitry Andric   //   parameter of type std::size_t is selected.
18550b57cec5SDimitry Andric   auto Best = resolveDeallocationOverload(
18560b57cec5SDimitry Andric       S, ops, /*WantSize*/false,
18570b57cec5SDimitry Andric       /*WantAlign*/hasNewExtendedAlignment(S, allocType));
18580b57cec5SDimitry Andric   return Best && Best.HasSizeT;
18590b57cec5SDimitry Andric }
18600b57cec5SDimitry Andric 
18610b57cec5SDimitry Andric /// Parsed a C++ 'new' expression (C++ 5.3.4).
18620b57cec5SDimitry Andric ///
18630b57cec5SDimitry Andric /// E.g.:
18640b57cec5SDimitry Andric /// @code new (memory) int[size][4] @endcode
18650b57cec5SDimitry Andric /// or
18660b57cec5SDimitry Andric /// @code ::new Foo(23, "hello") @endcode
18670b57cec5SDimitry Andric ///
18680b57cec5SDimitry Andric /// \param StartLoc The first location of the expression.
18690b57cec5SDimitry Andric /// \param UseGlobal True if 'new' was prefixed with '::'.
18700b57cec5SDimitry Andric /// \param PlacementLParen Opening paren of the placement arguments.
18710b57cec5SDimitry Andric /// \param PlacementArgs Placement new arguments.
18720b57cec5SDimitry Andric /// \param PlacementRParen Closing paren of the placement arguments.
18730b57cec5SDimitry Andric /// \param TypeIdParens If the type is in parens, the source range.
18740b57cec5SDimitry Andric /// \param D The type to be allocated, as well as array dimensions.
18750b57cec5SDimitry Andric /// \param Initializer The initializing expression or initializer-list, or null
18760b57cec5SDimitry Andric ///   if there is none.
18770b57cec5SDimitry Andric ExprResult
ActOnCXXNew(SourceLocation StartLoc,bool UseGlobal,SourceLocation PlacementLParen,MultiExprArg PlacementArgs,SourceLocation PlacementRParen,SourceRange TypeIdParens,Declarator & D,Expr * Initializer)18780b57cec5SDimitry Andric Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
18790b57cec5SDimitry Andric                   SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
18800b57cec5SDimitry Andric                   SourceLocation PlacementRParen, SourceRange TypeIdParens,
18810b57cec5SDimitry Andric                   Declarator &D, Expr *Initializer) {
1882bdd1243dSDimitry Andric   std::optional<Expr *> ArraySize;
18830b57cec5SDimitry Andric   // If the specified type is an array, unwrap it and save the expression.
18840b57cec5SDimitry Andric   if (D.getNumTypeObjects() > 0 &&
18850b57cec5SDimitry Andric       D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
18860b57cec5SDimitry Andric     DeclaratorChunk &Chunk = D.getTypeObject(0);
18870b57cec5SDimitry Andric     if (D.getDeclSpec().hasAutoTypeSpec())
18880b57cec5SDimitry Andric       return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto)
18890b57cec5SDimitry Andric         << D.getSourceRange());
18900b57cec5SDimitry Andric     if (Chunk.Arr.hasStatic)
18910b57cec5SDimitry Andric       return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new)
18920b57cec5SDimitry Andric         << D.getSourceRange());
18930b57cec5SDimitry Andric     if (!Chunk.Arr.NumElts && !Initializer)
18940b57cec5SDimitry Andric       return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size)
18950b57cec5SDimitry Andric         << D.getSourceRange());
18960b57cec5SDimitry Andric 
18970b57cec5SDimitry Andric     ArraySize = static_cast<Expr*>(Chunk.Arr.NumElts);
18980b57cec5SDimitry Andric     D.DropFirstTypeObject();
18990b57cec5SDimitry Andric   }
19000b57cec5SDimitry Andric 
19010b57cec5SDimitry Andric   // Every dimension shall be of constant size.
19020b57cec5SDimitry Andric   if (ArraySize) {
19030b57cec5SDimitry Andric     for (unsigned I = 0, N = D.getNumTypeObjects(); I < N; ++I) {
19040b57cec5SDimitry Andric       if (D.getTypeObject(I).Kind != DeclaratorChunk::Array)
19050b57cec5SDimitry Andric         break;
19060b57cec5SDimitry Andric 
19070b57cec5SDimitry Andric       DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr;
19080b57cec5SDimitry Andric       if (Expr *NumElts = (Expr *)Array.NumElts) {
19090b57cec5SDimitry Andric         if (!NumElts->isTypeDependent() && !NumElts->isValueDependent()) {
1910e8d8bef9SDimitry Andric           // FIXME: GCC permits constant folding here. We should either do so consistently
1911e8d8bef9SDimitry Andric           // or not do so at all, rather than changing behavior in C++14 onwards.
19120b57cec5SDimitry Andric           if (getLangOpts().CPlusPlus14) {
19130b57cec5SDimitry Andric             // C++1y [expr.new]p6: Every constant-expression in a noptr-new-declarator
19140b57cec5SDimitry Andric             //   shall be a converted constant expression (5.19) of type std::size_t
19150b57cec5SDimitry Andric             //   and shall evaluate to a strictly positive value.
1916e8d8bef9SDimitry Andric             llvm::APSInt Value(Context.getIntWidth(Context.getSizeType()));
19170b57cec5SDimitry Andric             Array.NumElts
19180b57cec5SDimitry Andric              = CheckConvertedConstantExpression(NumElts, Context.getSizeType(), Value,
1919e8d8bef9SDimitry Andric                                                 CCEK_ArrayBound)
19200b57cec5SDimitry Andric                  .get();
19210b57cec5SDimitry Andric           } else {
1922e8d8bef9SDimitry Andric             Array.NumElts =
1923e8d8bef9SDimitry Andric                 VerifyIntegerConstantExpression(
1924e8d8bef9SDimitry Andric                     NumElts, nullptr, diag::err_new_array_nonconst, AllowFold)
19250b57cec5SDimitry Andric                     .get();
19260b57cec5SDimitry Andric           }
19270b57cec5SDimitry Andric           if (!Array.NumElts)
19280b57cec5SDimitry Andric             return ExprError();
19290b57cec5SDimitry Andric         }
19300b57cec5SDimitry Andric       }
19310b57cec5SDimitry Andric     }
19320b57cec5SDimitry Andric   }
19330b57cec5SDimitry Andric 
19347a6dacacSDimitry Andric   TypeSourceInfo *TInfo = GetTypeForDeclarator(D);
19350b57cec5SDimitry Andric   QualType AllocType = TInfo->getType();
19360b57cec5SDimitry Andric   if (D.isInvalidType())
19370b57cec5SDimitry Andric     return ExprError();
19380b57cec5SDimitry Andric 
19390b57cec5SDimitry Andric   SourceRange DirectInitRange;
19400b57cec5SDimitry Andric   if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer))
19410b57cec5SDimitry Andric     DirectInitRange = List->getSourceRange();
19420b57cec5SDimitry Andric 
19430b57cec5SDimitry Andric   return BuildCXXNew(SourceRange(StartLoc, D.getEndLoc()), UseGlobal,
19440b57cec5SDimitry Andric                      PlacementLParen, PlacementArgs, PlacementRParen,
19450b57cec5SDimitry Andric                      TypeIdParens, AllocType, TInfo, ArraySize, DirectInitRange,
19460b57cec5SDimitry Andric                      Initializer);
19470b57cec5SDimitry Andric }
19480b57cec5SDimitry Andric 
isLegalArrayNewInitializer(CXXNewInitializationStyle Style,Expr * Init,bool IsCPlusPlus20)19495f757f3fSDimitry Andric static bool isLegalArrayNewInitializer(CXXNewInitializationStyle Style,
19507a6dacacSDimitry Andric                                        Expr *Init, bool IsCPlusPlus20) {
19510b57cec5SDimitry Andric   if (!Init)
19520b57cec5SDimitry Andric     return true;
19530b57cec5SDimitry Andric   if (ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init))
19547a6dacacSDimitry Andric     return IsCPlusPlus20 || PLE->getNumExprs() == 0;
19550b57cec5SDimitry Andric   if (isa<ImplicitValueInitExpr>(Init))
19560b57cec5SDimitry Andric     return true;
19570b57cec5SDimitry Andric   else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init))
19580b57cec5SDimitry Andric     return !CCE->isListInitialization() &&
19590b57cec5SDimitry Andric            CCE->getConstructor()->isDefaultConstructor();
19607a6dacacSDimitry Andric   else if (Style == CXXNewInitializationStyle::Braces) {
19610b57cec5SDimitry Andric     assert(isa<InitListExpr>(Init) &&
19620b57cec5SDimitry Andric            "Shouldn't create list CXXConstructExprs for arrays.");
19630b57cec5SDimitry Andric     return true;
19640b57cec5SDimitry Andric   }
19650b57cec5SDimitry Andric   return false;
19660b57cec5SDimitry Andric }
19670b57cec5SDimitry Andric 
19680b57cec5SDimitry Andric bool
isUnavailableAlignedAllocationFunction(const FunctionDecl & FD) const19690b57cec5SDimitry Andric Sema::isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const {
19700b57cec5SDimitry Andric   if (!getLangOpts().AlignedAllocationUnavailable)
19710b57cec5SDimitry Andric     return false;
19720b57cec5SDimitry Andric   if (FD.isDefined())
19730b57cec5SDimitry Andric     return false;
1974bdd1243dSDimitry Andric   std::optional<unsigned> AlignmentParam;
19755ffd83dbSDimitry Andric   if (FD.isReplaceableGlobalAllocationFunction(&AlignmentParam) &&
197681ad6265SDimitry Andric       AlignmentParam)
19770b57cec5SDimitry Andric     return true;
19780b57cec5SDimitry Andric   return false;
19790b57cec5SDimitry Andric }
19800b57cec5SDimitry Andric 
19810b57cec5SDimitry Andric // Emit a diagnostic if an aligned allocation/deallocation function that is not
19820b57cec5SDimitry Andric // implemented in the standard library is selected.
diagnoseUnavailableAlignedAllocation(const FunctionDecl & FD,SourceLocation Loc)19830b57cec5SDimitry Andric void Sema::diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
19840b57cec5SDimitry Andric                                                 SourceLocation Loc) {
19850b57cec5SDimitry Andric   if (isUnavailableAlignedAllocationFunction(FD)) {
19860b57cec5SDimitry Andric     const llvm::Triple &T = getASTContext().getTargetInfo().getTriple();
19870b57cec5SDimitry Andric     StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling(
19880b57cec5SDimitry Andric         getASTContext().getTargetInfo().getPlatformName());
1989e8d8bef9SDimitry Andric     VersionTuple OSVersion = alignedAllocMinVersion(T.getOS());
19900b57cec5SDimitry Andric 
19910b57cec5SDimitry Andric     OverloadedOperatorKind Kind = FD.getDeclName().getCXXOverloadedOperator();
19920b57cec5SDimitry Andric     bool IsDelete = Kind == OO_Delete || Kind == OO_Array_Delete;
19930b57cec5SDimitry Andric     Diag(Loc, diag::err_aligned_allocation_unavailable)
19940b57cec5SDimitry Andric         << IsDelete << FD.getType().getAsString() << OSName
1995e8d8bef9SDimitry Andric         << OSVersion.getAsString() << OSVersion.empty();
19960b57cec5SDimitry Andric     Diag(Loc, diag::note_silence_aligned_allocation_unavailable);
19970b57cec5SDimitry Andric   }
19980b57cec5SDimitry Andric }
19990b57cec5SDimitry Andric 
BuildCXXNew(SourceRange Range,bool UseGlobal,SourceLocation PlacementLParen,MultiExprArg PlacementArgs,SourceLocation PlacementRParen,SourceRange TypeIdParens,QualType AllocType,TypeSourceInfo * AllocTypeInfo,std::optional<Expr * > ArraySize,SourceRange DirectInitRange,Expr * Initializer)2000bdd1243dSDimitry Andric ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
20010b57cec5SDimitry Andric                              SourceLocation PlacementLParen,
20020b57cec5SDimitry Andric                              MultiExprArg PlacementArgs,
20030b57cec5SDimitry Andric                              SourceLocation PlacementRParen,
2004bdd1243dSDimitry Andric                              SourceRange TypeIdParens, QualType AllocType,
20050b57cec5SDimitry Andric                              TypeSourceInfo *AllocTypeInfo,
2006bdd1243dSDimitry Andric                              std::optional<Expr *> ArraySize,
2007bdd1243dSDimitry Andric                              SourceRange DirectInitRange, Expr *Initializer) {
20080b57cec5SDimitry Andric   SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
20090b57cec5SDimitry Andric   SourceLocation StartLoc = Range.getBegin();
20100b57cec5SDimitry Andric 
20115f757f3fSDimitry Andric   CXXNewInitializationStyle InitStyle;
20120b57cec5SDimitry Andric   if (DirectInitRange.isValid()) {
20130b57cec5SDimitry Andric     assert(Initializer && "Have parens but no initializer.");
20147a6dacacSDimitry Andric     InitStyle = CXXNewInitializationStyle::Parens;
20150b57cec5SDimitry Andric   } else if (Initializer && isa<InitListExpr>(Initializer))
20167a6dacacSDimitry Andric     InitStyle = CXXNewInitializationStyle::Braces;
20170b57cec5SDimitry Andric   else {
20180b57cec5SDimitry Andric     assert((!Initializer || isa<ImplicitValueInitExpr>(Initializer) ||
20190b57cec5SDimitry Andric             isa<CXXConstructExpr>(Initializer)) &&
20200b57cec5SDimitry Andric            "Initializer expression that cannot have been implicitly created.");
20215f757f3fSDimitry Andric     InitStyle = CXXNewInitializationStyle::None;
20220b57cec5SDimitry Andric   }
20230b57cec5SDimitry Andric 
202481ad6265SDimitry Andric   MultiExprArg Exprs(&Initializer, Initializer ? 1 : 0);
20250b57cec5SDimitry Andric   if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer)) {
20267a6dacacSDimitry Andric     assert(InitStyle == CXXNewInitializationStyle::Parens &&
20275f757f3fSDimitry Andric            "paren init for non-call init");
202881ad6265SDimitry Andric     Exprs = MultiExprArg(List->getExprs(), List->getNumExprs());
20290b57cec5SDimitry Andric   }
20300b57cec5SDimitry Andric 
20310b57cec5SDimitry Andric   // C++11 [expr.new]p15:
20320b57cec5SDimitry Andric   //   A new-expression that creates an object of type T initializes that
20330b57cec5SDimitry Andric   //   object as follows:
20345f757f3fSDimitry Andric   InitializationKind Kind = [&] {
20355f757f3fSDimitry Andric     switch (InitStyle) {
20360b57cec5SDimitry Andric     //     - If the new-initializer is omitted, the object is default-
20370b57cec5SDimitry Andric     //       initialized (8.5); if no initialization is performed,
20380b57cec5SDimitry Andric     //       the object has indeterminate value
20395f757f3fSDimitry Andric     case CXXNewInitializationStyle::None:
20405f757f3fSDimitry Andric       return InitializationKind::CreateDefault(TypeRange.getBegin());
20415f757f3fSDimitry Andric     //     - Otherwise, the new-initializer is interpreted according to the
20420b57cec5SDimitry Andric     //       initialization rules of 8.5 for direct-initialization.
20437a6dacacSDimitry Andric     case CXXNewInitializationStyle::Parens:
20445f757f3fSDimitry Andric       return InitializationKind::CreateDirect(TypeRange.getBegin(),
20450b57cec5SDimitry Andric                                               DirectInitRange.getBegin(),
20460b57cec5SDimitry Andric                                               DirectInitRange.getEnd());
20477a6dacacSDimitry Andric     case CXXNewInitializationStyle::Braces:
20485f757f3fSDimitry Andric       return InitializationKind::CreateDirectList(TypeRange.getBegin(),
20495f757f3fSDimitry Andric                                                   Initializer->getBeginLoc(),
20505f757f3fSDimitry Andric                                                   Initializer->getEndLoc());
20515f757f3fSDimitry Andric     }
20525f757f3fSDimitry Andric     llvm_unreachable("Unknown initialization kind");
20535f757f3fSDimitry Andric   }();
20540b57cec5SDimitry Andric 
20550b57cec5SDimitry Andric   // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
20560b57cec5SDimitry Andric   auto *Deduced = AllocType->getContainedDeducedType();
20571ac55f4cSDimitry Andric   if (Deduced && !Deduced->isDeduced() &&
20581ac55f4cSDimitry Andric       isa<DeducedTemplateSpecializationType>(Deduced)) {
20590b57cec5SDimitry Andric     if (ArraySize)
20600b57cec5SDimitry Andric       return ExprError(
2061349cc55cSDimitry Andric           Diag(*ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(),
20620b57cec5SDimitry Andric                diag::err_deduced_class_template_compound_type)
20630b57cec5SDimitry Andric           << /*array*/ 2
2064349cc55cSDimitry Andric           << (*ArraySize ? (*ArraySize)->getSourceRange() : TypeRange));
20650b57cec5SDimitry Andric 
20660b57cec5SDimitry Andric     InitializedEntity Entity
20670b57cec5SDimitry Andric       = InitializedEntity::InitializeNew(StartLoc, AllocType);
20680b57cec5SDimitry Andric     AllocType = DeduceTemplateSpecializationFromInitializer(
206981ad6265SDimitry Andric         AllocTypeInfo, Entity, Kind, Exprs);
20700b57cec5SDimitry Andric     if (AllocType.isNull())
20710b57cec5SDimitry Andric       return ExprError();
20721ac55f4cSDimitry Andric   } else if (Deduced && !Deduced->isDeduced()) {
207381ad6265SDimitry Andric     MultiExprArg Inits = Exprs;
20747a6dacacSDimitry Andric     bool Braced = (InitStyle == CXXNewInitializationStyle::Braces);
207581ad6265SDimitry Andric     if (Braced) {
207681ad6265SDimitry Andric       auto *ILE = cast<InitListExpr>(Exprs[0]);
207781ad6265SDimitry Andric       Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits());
20780b57cec5SDimitry Andric     }
20790b57cec5SDimitry Andric 
20807a6dacacSDimitry Andric     if (InitStyle == CXXNewInitializationStyle::None || Inits.empty())
20810b57cec5SDimitry Andric       return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
20820b57cec5SDimitry Andric                        << AllocType << TypeRange);
208381ad6265SDimitry Andric     if (Inits.size() > 1) {
20840b57cec5SDimitry Andric       Expr *FirstBad = Inits[1];
20850b57cec5SDimitry Andric       return ExprError(Diag(FirstBad->getBeginLoc(),
20860b57cec5SDimitry Andric                             diag::err_auto_new_ctor_multiple_expressions)
20870b57cec5SDimitry Andric                        << AllocType << TypeRange);
20880b57cec5SDimitry Andric     }
20890b57cec5SDimitry Andric     if (Braced && !getLangOpts().CPlusPlus17)
20900b57cec5SDimitry Andric       Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init)
20910b57cec5SDimitry Andric           << AllocType << TypeRange;
20920b57cec5SDimitry Andric     Expr *Deduce = Inits[0];
209381ad6265SDimitry Andric     if (isa<InitListExpr>(Deduce))
209481ad6265SDimitry Andric       return ExprError(
209581ad6265SDimitry Andric           Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces)
209681ad6265SDimitry Andric           << Braced << AllocType << TypeRange);
20970b57cec5SDimitry Andric     QualType DeducedType;
2098bdd1243dSDimitry Andric     TemplateDeductionInfo Info(Deduce->getExprLoc());
2099bdd1243dSDimitry Andric     TemplateDeductionResult Result =
2100bdd1243dSDimitry Andric         DeduceAutoType(AllocTypeInfo->getTypeLoc(), Deduce, DeducedType, Info);
2101bdd1243dSDimitry Andric     if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed)
21020b57cec5SDimitry Andric       return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
2103bdd1243dSDimitry Andric                        << AllocType << Deduce->getType() << TypeRange
2104bdd1243dSDimitry Andric                        << Deduce->getSourceRange());
2105bdd1243dSDimitry Andric     if (DeducedType.isNull()) {
2106bdd1243dSDimitry Andric       assert(Result == TDK_AlreadyDiagnosed);
21070b57cec5SDimitry Andric       return ExprError();
2108bdd1243dSDimitry Andric     }
21090b57cec5SDimitry Andric     AllocType = DeducedType;
21100b57cec5SDimitry Andric   }
21110b57cec5SDimitry Andric 
21120b57cec5SDimitry Andric   // Per C++0x [expr.new]p5, the type being constructed may be a
21130b57cec5SDimitry Andric   // typedef of an array type.
21140b57cec5SDimitry Andric   if (!ArraySize) {
21150b57cec5SDimitry Andric     if (const ConstantArrayType *Array
21160b57cec5SDimitry Andric                               = Context.getAsConstantArrayType(AllocType)) {
21170b57cec5SDimitry Andric       ArraySize = IntegerLiteral::Create(Context, Array->getSize(),
21180b57cec5SDimitry Andric                                          Context.getSizeType(),
21190b57cec5SDimitry Andric                                          TypeRange.getEnd());
21200b57cec5SDimitry Andric       AllocType = Array->getElementType();
21210b57cec5SDimitry Andric     }
21220b57cec5SDimitry Andric   }
21230b57cec5SDimitry Andric 
21240b57cec5SDimitry Andric   if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange))
21250b57cec5SDimitry Andric     return ExprError();
21260b57cec5SDimitry Andric 
2127bdd1243dSDimitry Andric   if (ArraySize && !checkArrayElementAlignment(AllocType, TypeRange.getBegin()))
2128bdd1243dSDimitry Andric     return ExprError();
2129bdd1243dSDimitry Andric 
21300b57cec5SDimitry Andric   // In ARC, infer 'retaining' for the allocated
21310b57cec5SDimitry Andric   if (getLangOpts().ObjCAutoRefCount &&
21320b57cec5SDimitry Andric       AllocType.getObjCLifetime() == Qualifiers::OCL_None &&
21330b57cec5SDimitry Andric       AllocType->isObjCLifetimeType()) {
21340b57cec5SDimitry Andric     AllocType = Context.getLifetimeQualifiedType(AllocType,
21350b57cec5SDimitry Andric                                     AllocType->getObjCARCImplicitLifetime());
21360b57cec5SDimitry Andric   }
21370b57cec5SDimitry Andric 
21380b57cec5SDimitry Andric   QualType ResultType = Context.getPointerType(AllocType);
21390b57cec5SDimitry Andric 
21400b57cec5SDimitry Andric   if (ArraySize && *ArraySize &&
21410b57cec5SDimitry Andric       (*ArraySize)->getType()->isNonOverloadPlaceholderType()) {
21420b57cec5SDimitry Andric     ExprResult result = CheckPlaceholderExpr(*ArraySize);
21430b57cec5SDimitry Andric     if (result.isInvalid()) return ExprError();
21440b57cec5SDimitry Andric     ArraySize = result.get();
21450b57cec5SDimitry Andric   }
21460b57cec5SDimitry Andric   // C++98 5.3.4p6: "The expression in a direct-new-declarator shall have
21470b57cec5SDimitry Andric   //   integral or enumeration type with a non-negative value."
21480b57cec5SDimitry Andric   // C++11 [expr.new]p6: The expression [...] shall be of integral or unscoped
21490b57cec5SDimitry Andric   //   enumeration type, or a class type for which a single non-explicit
21500b57cec5SDimitry Andric   //   conversion function to integral or unscoped enumeration type exists.
21510b57cec5SDimitry Andric   // C++1y [expr.new]p6: The expression [...] is implicitly converted to
21520b57cec5SDimitry Andric   //   std::size_t.
2153bdd1243dSDimitry Andric   std::optional<uint64_t> KnownArraySize;
21540b57cec5SDimitry Andric   if (ArraySize && *ArraySize && !(*ArraySize)->isTypeDependent()) {
21550b57cec5SDimitry Andric     ExprResult ConvertedSize;
21560b57cec5SDimitry Andric     if (getLangOpts().CPlusPlus14) {
21570b57cec5SDimitry Andric       assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?");
21580b57cec5SDimitry Andric 
21590b57cec5SDimitry Andric       ConvertedSize = PerformImplicitConversion(*ArraySize, Context.getSizeType(),
21600b57cec5SDimitry Andric                                                 AA_Converting);
21610b57cec5SDimitry Andric 
21620b57cec5SDimitry Andric       if (!ConvertedSize.isInvalid() &&
21630b57cec5SDimitry Andric           (*ArraySize)->getType()->getAs<RecordType>())
21640b57cec5SDimitry Andric         // Diagnose the compatibility of this conversion.
21650b57cec5SDimitry Andric         Diag(StartLoc, diag::warn_cxx98_compat_array_size_conversion)
21660b57cec5SDimitry Andric           << (*ArraySize)->getType() << 0 << "'size_t'";
21670b57cec5SDimitry Andric     } else {
21680b57cec5SDimitry Andric       class SizeConvertDiagnoser : public ICEConvertDiagnoser {
21690b57cec5SDimitry Andric       protected:
21700b57cec5SDimitry Andric         Expr *ArraySize;
21710b57cec5SDimitry Andric 
21720b57cec5SDimitry Andric       public:
21730b57cec5SDimitry Andric         SizeConvertDiagnoser(Expr *ArraySize)
21740b57cec5SDimitry Andric             : ICEConvertDiagnoser(/*AllowScopedEnumerations*/false, false, false),
21750b57cec5SDimitry Andric               ArraySize(ArraySize) {}
21760b57cec5SDimitry Andric 
21770b57cec5SDimitry Andric         SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
21780b57cec5SDimitry Andric                                              QualType T) override {
21790b57cec5SDimitry Andric           return S.Diag(Loc, diag::err_array_size_not_integral)
21800b57cec5SDimitry Andric                    << S.getLangOpts().CPlusPlus11 << T;
21810b57cec5SDimitry Andric         }
21820b57cec5SDimitry Andric 
21830b57cec5SDimitry Andric         SemaDiagnosticBuilder diagnoseIncomplete(
21840b57cec5SDimitry Andric             Sema &S, SourceLocation Loc, QualType T) override {
21850b57cec5SDimitry Andric           return S.Diag(Loc, diag::err_array_size_incomplete_type)
21860b57cec5SDimitry Andric                    << T << ArraySize->getSourceRange();
21870b57cec5SDimitry Andric         }
21880b57cec5SDimitry Andric 
21890b57cec5SDimitry Andric         SemaDiagnosticBuilder diagnoseExplicitConv(
21900b57cec5SDimitry Andric             Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
21910b57cec5SDimitry Andric           return S.Diag(Loc, diag::err_array_size_explicit_conversion) << T << ConvTy;
21920b57cec5SDimitry Andric         }
21930b57cec5SDimitry Andric 
21940b57cec5SDimitry Andric         SemaDiagnosticBuilder noteExplicitConv(
21950b57cec5SDimitry Andric             Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
21960b57cec5SDimitry Andric           return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
21970b57cec5SDimitry Andric                    << ConvTy->isEnumeralType() << ConvTy;
21980b57cec5SDimitry Andric         }
21990b57cec5SDimitry Andric 
22000b57cec5SDimitry Andric         SemaDiagnosticBuilder diagnoseAmbiguous(
22010b57cec5SDimitry Andric             Sema &S, SourceLocation Loc, QualType T) override {
22020b57cec5SDimitry Andric           return S.Diag(Loc, diag::err_array_size_ambiguous_conversion) << T;
22030b57cec5SDimitry Andric         }
22040b57cec5SDimitry Andric 
22050b57cec5SDimitry Andric         SemaDiagnosticBuilder noteAmbiguous(
22060b57cec5SDimitry Andric             Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
22070b57cec5SDimitry Andric           return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
22080b57cec5SDimitry Andric                    << ConvTy->isEnumeralType() << ConvTy;
22090b57cec5SDimitry Andric         }
22100b57cec5SDimitry Andric 
22110b57cec5SDimitry Andric         SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc,
22120b57cec5SDimitry Andric                                                  QualType T,
22130b57cec5SDimitry Andric                                                  QualType ConvTy) override {
22140b57cec5SDimitry Andric           return S.Diag(Loc,
22150b57cec5SDimitry Andric                         S.getLangOpts().CPlusPlus11
22160b57cec5SDimitry Andric                           ? diag::warn_cxx98_compat_array_size_conversion
22170b57cec5SDimitry Andric                           : diag::ext_array_size_conversion)
22180b57cec5SDimitry Andric                    << T << ConvTy->isEnumeralType() << ConvTy;
22190b57cec5SDimitry Andric         }
22200b57cec5SDimitry Andric       } SizeDiagnoser(*ArraySize);
22210b57cec5SDimitry Andric 
22220b57cec5SDimitry Andric       ConvertedSize = PerformContextualImplicitConversion(StartLoc, *ArraySize,
22230b57cec5SDimitry Andric                                                           SizeDiagnoser);
22240b57cec5SDimitry Andric     }
22250b57cec5SDimitry Andric     if (ConvertedSize.isInvalid())
22260b57cec5SDimitry Andric       return ExprError();
22270b57cec5SDimitry Andric 
22280b57cec5SDimitry Andric     ArraySize = ConvertedSize.get();
22290b57cec5SDimitry Andric     QualType SizeType = (*ArraySize)->getType();
22300b57cec5SDimitry Andric 
22310b57cec5SDimitry Andric     if (!SizeType->isIntegralOrUnscopedEnumerationType())
22320b57cec5SDimitry Andric       return ExprError();
22330b57cec5SDimitry Andric 
22340b57cec5SDimitry Andric     // C++98 [expr.new]p7:
22350b57cec5SDimitry Andric     //   The expression in a direct-new-declarator shall have integral type
22360b57cec5SDimitry Andric     //   with a non-negative value.
22370b57cec5SDimitry Andric     //
22380b57cec5SDimitry Andric     // Let's see if this is a constant < 0. If so, we reject it out of hand,
22390b57cec5SDimitry Andric     // per CWG1464. Otherwise, if it's not a constant, we must have an
22400b57cec5SDimitry Andric     // unparenthesized array type.
2241349cc55cSDimitry Andric 
22420b57cec5SDimitry Andric     // We've already performed any required implicit conversion to integer or
22430b57cec5SDimitry Andric     // unscoped enumeration type.
22440b57cec5SDimitry Andric     // FIXME: Per CWG1464, we are required to check the value prior to
22450b57cec5SDimitry Andric     // converting to size_t. This will never find a negative array size in
22460b57cec5SDimitry Andric     // C++14 onwards, because Value is always unsigned here!
2247bdd1243dSDimitry Andric     if (std::optional<llvm::APSInt> Value =
2248e8d8bef9SDimitry Andric             (*ArraySize)->getIntegerConstantExpr(Context)) {
2249e8d8bef9SDimitry Andric       if (Value->isSigned() && Value->isNegative()) {
22500b57cec5SDimitry Andric         return ExprError(Diag((*ArraySize)->getBeginLoc(),
22510b57cec5SDimitry Andric                               diag::err_typecheck_negative_array_size)
22520b57cec5SDimitry Andric                          << (*ArraySize)->getSourceRange());
22530b57cec5SDimitry Andric       }
22540b57cec5SDimitry Andric 
22550b57cec5SDimitry Andric       if (!AllocType->isDependentType()) {
2256349cc55cSDimitry Andric         unsigned ActiveSizeBits =
2257349cc55cSDimitry Andric             ConstantArrayType::getNumAddressingBits(Context, AllocType, *Value);
22580b57cec5SDimitry Andric         if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context))
22590b57cec5SDimitry Andric           return ExprError(
22600b57cec5SDimitry Andric               Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large)
2261fe6060f1SDimitry Andric               << toString(*Value, 10) << (*ArraySize)->getSourceRange());
22620b57cec5SDimitry Andric       }
22630b57cec5SDimitry Andric 
2264e8d8bef9SDimitry Andric       KnownArraySize = Value->getZExtValue();
22650b57cec5SDimitry Andric     } else if (TypeIdParens.isValid()) {
22660b57cec5SDimitry Andric       // Can't have dynamic array size when the type-id is in parentheses.
22670b57cec5SDimitry Andric       Diag((*ArraySize)->getBeginLoc(), diag::ext_new_paren_array_nonconst)
22680b57cec5SDimitry Andric           << (*ArraySize)->getSourceRange()
22690b57cec5SDimitry Andric           << FixItHint::CreateRemoval(TypeIdParens.getBegin())
22700b57cec5SDimitry Andric           << FixItHint::CreateRemoval(TypeIdParens.getEnd());
22710b57cec5SDimitry Andric 
22720b57cec5SDimitry Andric       TypeIdParens = SourceRange();
22730b57cec5SDimitry Andric     }
22740b57cec5SDimitry Andric 
22750b57cec5SDimitry Andric     // Note that we do *not* convert the argument in any way.  It can
22760b57cec5SDimitry Andric     // be signed, larger than size_t, whatever.
22770b57cec5SDimitry Andric   }
22780b57cec5SDimitry Andric 
22790b57cec5SDimitry Andric   FunctionDecl *OperatorNew = nullptr;
22800b57cec5SDimitry Andric   FunctionDecl *OperatorDelete = nullptr;
22810b57cec5SDimitry Andric   unsigned Alignment =
22820b57cec5SDimitry Andric       AllocType->isDependentType() ? 0 : Context.getTypeAlign(AllocType);
22830b57cec5SDimitry Andric   unsigned NewAlignment = Context.getTargetInfo().getNewAlign();
22840b57cec5SDimitry Andric   bool PassAlignment = getLangOpts().AlignedAllocation &&
22850b57cec5SDimitry Andric                        Alignment > NewAlignment;
22860b57cec5SDimitry Andric 
22877a6dacacSDimitry Andric   if (CheckArgsForPlaceholders(PlacementArgs))
22887a6dacacSDimitry Andric     return ExprError();
22897a6dacacSDimitry Andric 
22900b57cec5SDimitry Andric   AllocationFunctionScope Scope = UseGlobal ? AFS_Global : AFS_Both;
22910b57cec5SDimitry Andric   if (!AllocType->isDependentType() &&
22920b57cec5SDimitry Andric       !Expr::hasAnyTypeDependentArguments(PlacementArgs) &&
22930b57cec5SDimitry Andric       FindAllocationFunctions(
22940b57cec5SDimitry Andric           StartLoc, SourceRange(PlacementLParen, PlacementRParen), Scope, Scope,
229581ad6265SDimitry Andric           AllocType, ArraySize.has_value(), PassAlignment, PlacementArgs,
22960b57cec5SDimitry Andric           OperatorNew, OperatorDelete))
22970b57cec5SDimitry Andric     return ExprError();
22980b57cec5SDimitry Andric 
22990b57cec5SDimitry Andric   // If this is an array allocation, compute whether the usual array
23000b57cec5SDimitry Andric   // deallocation function for the type has a size_t parameter.
23010b57cec5SDimitry Andric   bool UsualArrayDeleteWantsSize = false;
23020b57cec5SDimitry Andric   if (ArraySize && !AllocType->isDependentType())
23030b57cec5SDimitry Andric     UsualArrayDeleteWantsSize =
23040b57cec5SDimitry Andric         doesUsualArrayDeleteWantSize(*this, StartLoc, AllocType);
23050b57cec5SDimitry Andric 
23060b57cec5SDimitry Andric   SmallVector<Expr *, 8> AllPlaceArgs;
23070b57cec5SDimitry Andric   if (OperatorNew) {
23085ffd83dbSDimitry Andric     auto *Proto = OperatorNew->getType()->castAs<FunctionProtoType>();
23090b57cec5SDimitry Andric     VariadicCallType CallType = Proto->isVariadic() ? VariadicFunction
23100b57cec5SDimitry Andric                                                     : VariadicDoesNotApply;
23110b57cec5SDimitry Andric 
23120b57cec5SDimitry Andric     // We've already converted the placement args, just fill in any default
23130b57cec5SDimitry Andric     // arguments. Skip the first parameter because we don't have a corresponding
23140b57cec5SDimitry Andric     // argument. Skip the second parameter too if we're passing in the
23150b57cec5SDimitry Andric     // alignment; we've already filled it in.
23165ffd83dbSDimitry Andric     unsigned NumImplicitArgs = PassAlignment ? 2 : 1;
23170b57cec5SDimitry Andric     if (GatherArgumentsForCall(PlacementLParen, OperatorNew, Proto,
23185ffd83dbSDimitry Andric                                NumImplicitArgs, PlacementArgs, AllPlaceArgs,
23195ffd83dbSDimitry Andric                                CallType))
23200b57cec5SDimitry Andric       return ExprError();
23210b57cec5SDimitry Andric 
23220b57cec5SDimitry Andric     if (!AllPlaceArgs.empty())
23230b57cec5SDimitry Andric       PlacementArgs = AllPlaceArgs;
23240b57cec5SDimitry Andric 
23255ffd83dbSDimitry Andric     // We would like to perform some checking on the given `operator new` call,
23265ffd83dbSDimitry Andric     // but the PlacementArgs does not contain the implicit arguments,
23275ffd83dbSDimitry Andric     // namely allocation size and maybe allocation alignment,
23285ffd83dbSDimitry Andric     // so we need to conjure them.
23290b57cec5SDimitry Andric 
23305ffd83dbSDimitry Andric     QualType SizeTy = Context.getSizeType();
23315ffd83dbSDimitry Andric     unsigned SizeTyWidth = Context.getTypeSize(SizeTy);
23325ffd83dbSDimitry Andric 
23335ffd83dbSDimitry Andric     llvm::APInt SingleEltSize(
23345ffd83dbSDimitry Andric         SizeTyWidth, Context.getTypeSizeInChars(AllocType).getQuantity());
23355ffd83dbSDimitry Andric 
23365ffd83dbSDimitry Andric     // How many bytes do we want to allocate here?
2337bdd1243dSDimitry Andric     std::optional<llvm::APInt> AllocationSize;
233881ad6265SDimitry Andric     if (!ArraySize && !AllocType->isDependentType()) {
23395ffd83dbSDimitry Andric       // For non-array operator new, we only want to allocate one element.
23405ffd83dbSDimitry Andric       AllocationSize = SingleEltSize;
234181ad6265SDimitry Andric     } else if (KnownArraySize && !AllocType->isDependentType()) {
23425ffd83dbSDimitry Andric       // For array operator new, only deal with static array size case.
23435ffd83dbSDimitry Andric       bool Overflow;
23445ffd83dbSDimitry Andric       AllocationSize = llvm::APInt(SizeTyWidth, *KnownArraySize)
23455ffd83dbSDimitry Andric                            .umul_ov(SingleEltSize, Overflow);
23465ffd83dbSDimitry Andric       (void)Overflow;
23475ffd83dbSDimitry Andric       assert(
23485ffd83dbSDimitry Andric           !Overflow &&
23495ffd83dbSDimitry Andric           "Expected that all the overflows would have been handled already.");
23505ffd83dbSDimitry Andric     }
23515ffd83dbSDimitry Andric 
23525ffd83dbSDimitry Andric     IntegerLiteral AllocationSizeLiteral(
235381ad6265SDimitry Andric         Context, AllocationSize.value_or(llvm::APInt::getZero(SizeTyWidth)),
23545ffd83dbSDimitry Andric         SizeTy, SourceLocation());
23555ffd83dbSDimitry Andric     // Otherwise, if we failed to constant-fold the allocation size, we'll
23565ffd83dbSDimitry Andric     // just give up and pass-in something opaque, that isn't a null pointer.
2357fe6060f1SDimitry Andric     OpaqueValueExpr OpaqueAllocationSize(SourceLocation(), SizeTy, VK_PRValue,
23585ffd83dbSDimitry Andric                                          OK_Ordinary, /*SourceExpr=*/nullptr);
23595ffd83dbSDimitry Andric 
23605ffd83dbSDimitry Andric     // Let's synthesize the alignment argument in case we will need it.
23615ffd83dbSDimitry Andric     // Since we *really* want to allocate these on stack, this is slightly ugly
23625ffd83dbSDimitry Andric     // because there might not be a `std::align_val_t` type.
23635ffd83dbSDimitry Andric     EnumDecl *StdAlignValT = getStdAlignValT();
23645ffd83dbSDimitry Andric     QualType AlignValT =
23655ffd83dbSDimitry Andric         StdAlignValT ? Context.getTypeDeclType(StdAlignValT) : SizeTy;
23665ffd83dbSDimitry Andric     IntegerLiteral AlignmentLiteral(
23675ffd83dbSDimitry Andric         Context,
23685ffd83dbSDimitry Andric         llvm::APInt(Context.getTypeSize(SizeTy),
23695ffd83dbSDimitry Andric                     Alignment / Context.getCharWidth()),
23705ffd83dbSDimitry Andric         SizeTy, SourceLocation());
23715ffd83dbSDimitry Andric     ImplicitCastExpr DesiredAlignment(ImplicitCastExpr::OnStack, AlignValT,
23725ffd83dbSDimitry Andric                                       CK_IntegralCast, &AlignmentLiteral,
2373fe6060f1SDimitry Andric                                       VK_PRValue, FPOptionsOverride());
23745ffd83dbSDimitry Andric 
23755ffd83dbSDimitry Andric     // Adjust placement args by prepending conjured size and alignment exprs.
23765ffd83dbSDimitry Andric     llvm::SmallVector<Expr *, 8> CallArgs;
23775ffd83dbSDimitry Andric     CallArgs.reserve(NumImplicitArgs + PlacementArgs.size());
237881ad6265SDimitry Andric     CallArgs.emplace_back(AllocationSize
23795ffd83dbSDimitry Andric                               ? static_cast<Expr *>(&AllocationSizeLiteral)
23805ffd83dbSDimitry Andric                               : &OpaqueAllocationSize);
23815ffd83dbSDimitry Andric     if (PassAlignment)
23825ffd83dbSDimitry Andric       CallArgs.emplace_back(&DesiredAlignment);
23835ffd83dbSDimitry Andric     CallArgs.insert(CallArgs.end(), PlacementArgs.begin(), PlacementArgs.end());
23845ffd83dbSDimitry Andric 
23855ffd83dbSDimitry Andric     DiagnoseSentinelCalls(OperatorNew, PlacementLParen, CallArgs);
23865ffd83dbSDimitry Andric 
23875ffd83dbSDimitry Andric     checkCall(OperatorNew, Proto, /*ThisArg=*/nullptr, CallArgs,
23885ffd83dbSDimitry Andric               /*IsMemberFunction=*/false, StartLoc, Range, CallType);
23890b57cec5SDimitry Andric 
23900b57cec5SDimitry Andric     // Warn if the type is over-aligned and is being allocated by (unaligned)
23910b57cec5SDimitry Andric     // global operator new.
23920b57cec5SDimitry Andric     if (PlacementArgs.empty() && !PassAlignment &&
23930b57cec5SDimitry Andric         (OperatorNew->isImplicit() ||
23940b57cec5SDimitry Andric          (OperatorNew->getBeginLoc().isValid() &&
23950b57cec5SDimitry Andric           getSourceManager().isInSystemHeader(OperatorNew->getBeginLoc())))) {
23960b57cec5SDimitry Andric       if (Alignment > NewAlignment)
23970b57cec5SDimitry Andric         Diag(StartLoc, diag::warn_overaligned_type)
23980b57cec5SDimitry Andric             << AllocType
23990b57cec5SDimitry Andric             << unsigned(Alignment / Context.getCharWidth())
24000b57cec5SDimitry Andric             << unsigned(NewAlignment / Context.getCharWidth());
24010b57cec5SDimitry Andric     }
24020b57cec5SDimitry Andric   }
24030b57cec5SDimitry Andric 
24040b57cec5SDimitry Andric   // Array 'new' can't have any initializers except empty parentheses.
24050b57cec5SDimitry Andric   // Initializer lists are also allowed, in C++11. Rely on the parser for the
24060b57cec5SDimitry Andric   // dialect distinction.
24077a6dacacSDimitry Andric   if (ArraySize && !isLegalArrayNewInitializer(InitStyle, Initializer,
24087a6dacacSDimitry Andric                                                getLangOpts().CPlusPlus20)) {
240981ad6265SDimitry Andric     SourceRange InitRange(Exprs.front()->getBeginLoc(),
241081ad6265SDimitry Andric                           Exprs.back()->getEndLoc());
24110b57cec5SDimitry Andric     Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
24120b57cec5SDimitry Andric     return ExprError();
24130b57cec5SDimitry Andric   }
24140b57cec5SDimitry Andric 
24150b57cec5SDimitry Andric   // If we can perform the initialization, and we've not already done so,
24160b57cec5SDimitry Andric   // do it now.
24170b57cec5SDimitry Andric   if (!AllocType->isDependentType() &&
241881ad6265SDimitry Andric       !Expr::hasAnyTypeDependentArguments(Exprs)) {
24190b57cec5SDimitry Andric     // The type we initialize is the complete type, including the array bound.
24200b57cec5SDimitry Andric     QualType InitType;
24210b57cec5SDimitry Andric     if (KnownArraySize)
24220b57cec5SDimitry Andric       InitType = Context.getConstantArrayType(
2423a7dea167SDimitry Andric           AllocType,
2424a7dea167SDimitry Andric           llvm::APInt(Context.getTypeSize(Context.getSizeType()),
24250b57cec5SDimitry Andric                       *KnownArraySize),
24265f757f3fSDimitry Andric           *ArraySize, ArraySizeModifier::Normal, 0);
24270b57cec5SDimitry Andric     else if (ArraySize)
24285f757f3fSDimitry Andric       InitType = Context.getIncompleteArrayType(AllocType,
24295f757f3fSDimitry Andric                                                 ArraySizeModifier::Normal, 0);
24300b57cec5SDimitry Andric     else
24310b57cec5SDimitry Andric       InitType = AllocType;
24320b57cec5SDimitry Andric 
24330b57cec5SDimitry Andric     InitializedEntity Entity
24340b57cec5SDimitry Andric       = InitializedEntity::InitializeNew(StartLoc, InitType);
243581ad6265SDimitry Andric     InitializationSequence InitSeq(*this, Entity, Kind, Exprs);
243681ad6265SDimitry Andric     ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, Exprs);
24370b57cec5SDimitry Andric     if (FullInit.isInvalid())
24380b57cec5SDimitry Andric       return ExprError();
24390b57cec5SDimitry Andric 
24400b57cec5SDimitry Andric     // FullInit is our initializer; strip off CXXBindTemporaryExprs, because
24410b57cec5SDimitry Andric     // we don't want the initialized object to be destructed.
24420b57cec5SDimitry Andric     // FIXME: We should not create these in the first place.
24430b57cec5SDimitry Andric     if (CXXBindTemporaryExpr *Binder =
24440b57cec5SDimitry Andric             dyn_cast_or_null<CXXBindTemporaryExpr>(FullInit.get()))
24450b57cec5SDimitry Andric       FullInit = Binder->getSubExpr();
24460b57cec5SDimitry Andric 
24470b57cec5SDimitry Andric     Initializer = FullInit.get();
24480b57cec5SDimitry Andric 
24490b57cec5SDimitry Andric     // FIXME: If we have a KnownArraySize, check that the array bound of the
24500b57cec5SDimitry Andric     // initializer is no greater than that constant value.
24510b57cec5SDimitry Andric 
24520b57cec5SDimitry Andric     if (ArraySize && !*ArraySize) {
24530b57cec5SDimitry Andric       auto *CAT = Context.getAsConstantArrayType(Initializer->getType());
24540b57cec5SDimitry Andric       if (CAT) {
24550b57cec5SDimitry Andric         // FIXME: Track that the array size was inferred rather than explicitly
24560b57cec5SDimitry Andric         // specified.
24570b57cec5SDimitry Andric         ArraySize = IntegerLiteral::Create(
24580b57cec5SDimitry Andric             Context, CAT->getSize(), Context.getSizeType(), TypeRange.getEnd());
24590b57cec5SDimitry Andric       } else {
24600b57cec5SDimitry Andric         Diag(TypeRange.getEnd(), diag::err_new_array_size_unknown_from_init)
24610b57cec5SDimitry Andric             << Initializer->getSourceRange();
24620b57cec5SDimitry Andric       }
24630b57cec5SDimitry Andric     }
24640b57cec5SDimitry Andric   }
24650b57cec5SDimitry Andric 
24660b57cec5SDimitry Andric   // Mark the new and delete operators as referenced.
24670b57cec5SDimitry Andric   if (OperatorNew) {
24680b57cec5SDimitry Andric     if (DiagnoseUseOfDecl(OperatorNew, StartLoc))
24690b57cec5SDimitry Andric       return ExprError();
24700b57cec5SDimitry Andric     MarkFunctionReferenced(StartLoc, OperatorNew);
24710b57cec5SDimitry Andric   }
24720b57cec5SDimitry Andric   if (OperatorDelete) {
24730b57cec5SDimitry Andric     if (DiagnoseUseOfDecl(OperatorDelete, StartLoc))
24740b57cec5SDimitry Andric       return ExprError();
24750b57cec5SDimitry Andric     MarkFunctionReferenced(StartLoc, OperatorDelete);
24760b57cec5SDimitry Andric   }
24770b57cec5SDimitry Andric 
24780b57cec5SDimitry Andric   return CXXNewExpr::Create(Context, UseGlobal, OperatorNew, OperatorDelete,
24790b57cec5SDimitry Andric                             PassAlignment, UsualArrayDeleteWantsSize,
24805f757f3fSDimitry Andric                             PlacementArgs, TypeIdParens, ArraySize, InitStyle,
24810b57cec5SDimitry Andric                             Initializer, ResultType, AllocTypeInfo, Range,
24820b57cec5SDimitry Andric                             DirectInitRange);
24830b57cec5SDimitry Andric }
24840b57cec5SDimitry Andric 
24850b57cec5SDimitry Andric /// Checks that a type is suitable as the allocated type
24860b57cec5SDimitry Andric /// in a new-expression.
CheckAllocatedType(QualType AllocType,SourceLocation Loc,SourceRange R)24870b57cec5SDimitry Andric bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
24880b57cec5SDimitry Andric                               SourceRange R) {
24890b57cec5SDimitry Andric   // C++ 5.3.4p1: "[The] type shall be a complete object type, but not an
24900b57cec5SDimitry Andric   //   abstract class type or array thereof.
24910b57cec5SDimitry Andric   if (AllocType->isFunctionType())
24920b57cec5SDimitry Andric     return Diag(Loc, diag::err_bad_new_type)
24930b57cec5SDimitry Andric       << AllocType << 0 << R;
24940b57cec5SDimitry Andric   else if (AllocType->isReferenceType())
24950b57cec5SDimitry Andric     return Diag(Loc, diag::err_bad_new_type)
24960b57cec5SDimitry Andric       << AllocType << 1 << R;
24970b57cec5SDimitry Andric   else if (!AllocType->isDependentType() &&
24985ffd83dbSDimitry Andric            RequireCompleteSizedType(
24995ffd83dbSDimitry Andric                Loc, AllocType, diag::err_new_incomplete_or_sizeless_type, R))
25000b57cec5SDimitry Andric     return true;
25010b57cec5SDimitry Andric   else if (RequireNonAbstractType(Loc, AllocType,
25020b57cec5SDimitry Andric                                   diag::err_allocation_of_abstract_type))
25030b57cec5SDimitry Andric     return true;
25040b57cec5SDimitry Andric   else if (AllocType->isVariablyModifiedType())
25050b57cec5SDimitry Andric     return Diag(Loc, diag::err_variably_modified_new_type)
25060b57cec5SDimitry Andric              << AllocType;
25070b57cec5SDimitry Andric   else if (AllocType.getAddressSpace() != LangAS::Default &&
25080b57cec5SDimitry Andric            !getLangOpts().OpenCLCPlusPlus)
25090b57cec5SDimitry Andric     return Diag(Loc, diag::err_address_space_qualified_new)
25100b57cec5SDimitry Andric       << AllocType.getUnqualifiedType()
25110b57cec5SDimitry Andric       << AllocType.getQualifiers().getAddressSpaceAttributePrintValue();
25120b57cec5SDimitry Andric   else if (getLangOpts().ObjCAutoRefCount) {
25130b57cec5SDimitry Andric     if (const ArrayType *AT = Context.getAsArrayType(AllocType)) {
25140b57cec5SDimitry Andric       QualType BaseAllocType = Context.getBaseElementType(AT);
25150b57cec5SDimitry Andric       if (BaseAllocType.getObjCLifetime() == Qualifiers::OCL_None &&
25160b57cec5SDimitry Andric           BaseAllocType->isObjCLifetimeType())
25170b57cec5SDimitry Andric         return Diag(Loc, diag::err_arc_new_array_without_ownership)
25180b57cec5SDimitry Andric           << BaseAllocType;
25190b57cec5SDimitry Andric     }
25200b57cec5SDimitry Andric   }
25210b57cec5SDimitry Andric 
25220b57cec5SDimitry Andric   return false;
25230b57cec5SDimitry Andric }
25240b57cec5SDimitry Andric 
resolveAllocationOverload(Sema & S,LookupResult & R,SourceRange Range,SmallVectorImpl<Expr * > & Args,bool & PassAlignment,FunctionDecl * & Operator,OverloadCandidateSet * AlignedCandidates,Expr * AlignArg,bool Diagnose)25250b57cec5SDimitry Andric static bool resolveAllocationOverload(
25260b57cec5SDimitry Andric     Sema &S, LookupResult &R, SourceRange Range, SmallVectorImpl<Expr *> &Args,
25270b57cec5SDimitry Andric     bool &PassAlignment, FunctionDecl *&Operator,
25280b57cec5SDimitry Andric     OverloadCandidateSet *AlignedCandidates, Expr *AlignArg, bool Diagnose) {
25290b57cec5SDimitry Andric   OverloadCandidateSet Candidates(R.getNameLoc(),
25300b57cec5SDimitry Andric                                   OverloadCandidateSet::CSK_Normal);
25310b57cec5SDimitry Andric   for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end();
25320b57cec5SDimitry Andric        Alloc != AllocEnd; ++Alloc) {
25330b57cec5SDimitry Andric     // Even member operator new/delete are implicitly treated as
25340b57cec5SDimitry Andric     // static, so don't use AddMemberCandidate.
25350b57cec5SDimitry Andric     NamedDecl *D = (*Alloc)->getUnderlyingDecl();
25360b57cec5SDimitry Andric 
25370b57cec5SDimitry Andric     if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl>(D)) {
25380b57cec5SDimitry Andric       S.AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(),
25390b57cec5SDimitry Andric                                      /*ExplicitTemplateArgs=*/nullptr, Args,
25400b57cec5SDimitry Andric                                      Candidates,
25410b57cec5SDimitry Andric                                      /*SuppressUserConversions=*/false);
25420b57cec5SDimitry Andric       continue;
25430b57cec5SDimitry Andric     }
25440b57cec5SDimitry Andric 
25450b57cec5SDimitry Andric     FunctionDecl *Fn = cast<FunctionDecl>(D);
25460b57cec5SDimitry Andric     S.AddOverloadCandidate(Fn, Alloc.getPair(), Args, Candidates,
25470b57cec5SDimitry Andric                            /*SuppressUserConversions=*/false);
25480b57cec5SDimitry Andric   }
25490b57cec5SDimitry Andric 
25500b57cec5SDimitry Andric   // Do the resolution.
25510b57cec5SDimitry Andric   OverloadCandidateSet::iterator Best;
25520b57cec5SDimitry Andric   switch (Candidates.BestViableFunction(S, R.getNameLoc(), Best)) {
25530b57cec5SDimitry Andric   case OR_Success: {
25540b57cec5SDimitry Andric     // Got one!
25550b57cec5SDimitry Andric     FunctionDecl *FnDecl = Best->Function;
25560b57cec5SDimitry Andric     if (S.CheckAllocationAccess(R.getNameLoc(), Range, R.getNamingClass(),
25570b57cec5SDimitry Andric                                 Best->FoundDecl) == Sema::AR_inaccessible)
25580b57cec5SDimitry Andric       return true;
25590b57cec5SDimitry Andric 
25600b57cec5SDimitry Andric     Operator = FnDecl;
25610b57cec5SDimitry Andric     return false;
25620b57cec5SDimitry Andric   }
25630b57cec5SDimitry Andric 
25640b57cec5SDimitry Andric   case OR_No_Viable_Function:
25650b57cec5SDimitry Andric     // C++17 [expr.new]p13:
25660b57cec5SDimitry Andric     //   If no matching function is found and the allocated object type has
25670b57cec5SDimitry Andric     //   new-extended alignment, the alignment argument is removed from the
25680b57cec5SDimitry Andric     //   argument list, and overload resolution is performed again.
25690b57cec5SDimitry Andric     if (PassAlignment) {
25700b57cec5SDimitry Andric       PassAlignment = false;
25710b57cec5SDimitry Andric       AlignArg = Args[1];
25720b57cec5SDimitry Andric       Args.erase(Args.begin() + 1);
25730b57cec5SDimitry Andric       return resolveAllocationOverload(S, R, Range, Args, PassAlignment,
25740b57cec5SDimitry Andric                                        Operator, &Candidates, AlignArg,
25750b57cec5SDimitry Andric                                        Diagnose);
25760b57cec5SDimitry Andric     }
25770b57cec5SDimitry Andric 
25780b57cec5SDimitry Andric     // MSVC will fall back on trying to find a matching global operator new
25790b57cec5SDimitry Andric     // if operator new[] cannot be found.  Also, MSVC will leak by not
25800b57cec5SDimitry Andric     // generating a call to operator delete or operator delete[], but we
25810b57cec5SDimitry Andric     // will not replicate that bug.
25820b57cec5SDimitry Andric     // FIXME: Find out how this interacts with the std::align_val_t fallback
25830b57cec5SDimitry Andric     // once MSVC implements it.
25840b57cec5SDimitry Andric     if (R.getLookupName().getCXXOverloadedOperator() == OO_Array_New &&
25850b57cec5SDimitry Andric         S.Context.getLangOpts().MSVCCompat) {
25860b57cec5SDimitry Andric       R.clear();
25870b57cec5SDimitry Andric       R.setLookupName(S.Context.DeclarationNames.getCXXOperatorName(OO_New));
25880b57cec5SDimitry Andric       S.LookupQualifiedName(R, S.Context.getTranslationUnitDecl());
25890b57cec5SDimitry Andric       // FIXME: This will give bad diagnostics pointing at the wrong functions.
25900b57cec5SDimitry Andric       return resolveAllocationOverload(S, R, Range, Args, PassAlignment,
25910b57cec5SDimitry Andric                                        Operator, /*Candidates=*/nullptr,
25920b57cec5SDimitry Andric                                        /*AlignArg=*/nullptr, Diagnose);
25930b57cec5SDimitry Andric     }
25940b57cec5SDimitry Andric 
25950b57cec5SDimitry Andric     if (Diagnose) {
2596fe6060f1SDimitry Andric       // If this is an allocation of the form 'new (p) X' for some object
2597fe6060f1SDimitry Andric       // pointer p (or an expression that will decay to such a pointer),
2598fe6060f1SDimitry Andric       // diagnose the missing inclusion of <new>.
2599fe6060f1SDimitry Andric       if (!R.isClassLookup() && Args.size() == 2 &&
2600fe6060f1SDimitry Andric           (Args[1]->getType()->isObjectPointerType() ||
2601fe6060f1SDimitry Andric            Args[1]->getType()->isArrayType())) {
2602fe6060f1SDimitry Andric         S.Diag(R.getNameLoc(), diag::err_need_header_before_placement_new)
2603fe6060f1SDimitry Andric             << R.getLookupName() << Range;
2604fe6060f1SDimitry Andric         // Listing the candidates is unlikely to be useful; skip it.
2605fe6060f1SDimitry Andric         return true;
2606fe6060f1SDimitry Andric       }
26070b57cec5SDimitry Andric 
2608fe6060f1SDimitry Andric       // Finish checking all candidates before we note any. This checking can
2609fe6060f1SDimitry Andric       // produce additional diagnostics so can't be interleaved with our
2610fe6060f1SDimitry Andric       // emission of notes.
2611fe6060f1SDimitry Andric       //
2612fe6060f1SDimitry Andric       // For an aligned allocation, separately check the aligned and unaligned
2613fe6060f1SDimitry Andric       // candidates with their respective argument lists.
2614fe6060f1SDimitry Andric       SmallVector<OverloadCandidate*, 32> Cands;
2615fe6060f1SDimitry Andric       SmallVector<OverloadCandidate*, 32> AlignedCands;
2616fe6060f1SDimitry Andric       llvm::SmallVector<Expr*, 4> AlignedArgs;
26170b57cec5SDimitry Andric       if (AlignedCandidates) {
26180b57cec5SDimitry Andric         auto IsAligned = [](OverloadCandidate &C) {
26190b57cec5SDimitry Andric           return C.Function->getNumParams() > 1 &&
26200b57cec5SDimitry Andric                  C.Function->getParamDecl(1)->getType()->isAlignValT();
26210b57cec5SDimitry Andric         };
26220b57cec5SDimitry Andric         auto IsUnaligned = [&](OverloadCandidate &C) { return !IsAligned(C); };
26230b57cec5SDimitry Andric 
2624fe6060f1SDimitry Andric         AlignedArgs.reserve(Args.size() + 1);
2625fe6060f1SDimitry Andric         AlignedArgs.push_back(Args[0]);
2626fe6060f1SDimitry Andric         AlignedArgs.push_back(AlignArg);
2627fe6060f1SDimitry Andric         AlignedArgs.append(Args.begin() + 1, Args.end());
2628fe6060f1SDimitry Andric         AlignedCands = AlignedCandidates->CompleteCandidates(
2629fe6060f1SDimitry Andric             S, OCD_AllCandidates, AlignedArgs, R.getNameLoc(), IsAligned);
2630fe6060f1SDimitry Andric 
2631fe6060f1SDimitry Andric         Cands = Candidates.CompleteCandidates(S, OCD_AllCandidates, Args,
2632fe6060f1SDimitry Andric                                               R.getNameLoc(), IsUnaligned);
26330b57cec5SDimitry Andric       } else {
2634fe6060f1SDimitry Andric         Cands = Candidates.CompleteCandidates(S, OCD_AllCandidates, Args,
2635fe6060f1SDimitry Andric                                               R.getNameLoc());
26360b57cec5SDimitry Andric       }
2637fe6060f1SDimitry Andric 
2638fe6060f1SDimitry Andric       S.Diag(R.getNameLoc(), diag::err_ovl_no_viable_function_in_call)
2639fe6060f1SDimitry Andric           << R.getLookupName() << Range;
2640fe6060f1SDimitry Andric       if (AlignedCandidates)
2641fe6060f1SDimitry Andric         AlignedCandidates->NoteCandidates(S, AlignedArgs, AlignedCands, "",
2642fe6060f1SDimitry Andric                                           R.getNameLoc());
2643fe6060f1SDimitry Andric       Candidates.NoteCandidates(S, Args, Cands, "", R.getNameLoc());
26440b57cec5SDimitry Andric     }
26450b57cec5SDimitry Andric     return true;
26460b57cec5SDimitry Andric 
26470b57cec5SDimitry Andric   case OR_Ambiguous:
26480b57cec5SDimitry Andric     if (Diagnose) {
26490b57cec5SDimitry Andric       Candidates.NoteCandidates(
26500b57cec5SDimitry Andric           PartialDiagnosticAt(R.getNameLoc(),
26510b57cec5SDimitry Andric                               S.PDiag(diag::err_ovl_ambiguous_call)
26520b57cec5SDimitry Andric                                   << R.getLookupName() << Range),
2653480093f4SDimitry Andric           S, OCD_AmbiguousCandidates, Args);
26540b57cec5SDimitry Andric     }
26550b57cec5SDimitry Andric     return true;
26560b57cec5SDimitry Andric 
26570b57cec5SDimitry Andric   case OR_Deleted: {
26580b57cec5SDimitry Andric     if (Diagnose) {
26590b57cec5SDimitry Andric       Candidates.NoteCandidates(
26600b57cec5SDimitry Andric           PartialDiagnosticAt(R.getNameLoc(),
26610b57cec5SDimitry Andric                               S.PDiag(diag::err_ovl_deleted_call)
26620b57cec5SDimitry Andric                                   << R.getLookupName() << Range),
26630b57cec5SDimitry Andric           S, OCD_AllCandidates, Args);
26640b57cec5SDimitry Andric     }
26650b57cec5SDimitry Andric     return true;
26660b57cec5SDimitry Andric   }
26670b57cec5SDimitry Andric   }
26680b57cec5SDimitry Andric   llvm_unreachable("Unreachable, bad result from BestViableFunction");
26690b57cec5SDimitry Andric }
26700b57cec5SDimitry Andric 
FindAllocationFunctions(SourceLocation StartLoc,SourceRange Range,AllocationFunctionScope NewScope,AllocationFunctionScope DeleteScope,QualType AllocType,bool IsArray,bool & PassAlignment,MultiExprArg PlaceArgs,FunctionDecl * & OperatorNew,FunctionDecl * & OperatorDelete,bool Diagnose)26710b57cec5SDimitry Andric bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
26720b57cec5SDimitry Andric                                    AllocationFunctionScope NewScope,
26730b57cec5SDimitry Andric                                    AllocationFunctionScope DeleteScope,
26740b57cec5SDimitry Andric                                    QualType AllocType, bool IsArray,
26750b57cec5SDimitry Andric                                    bool &PassAlignment, MultiExprArg PlaceArgs,
26760b57cec5SDimitry Andric                                    FunctionDecl *&OperatorNew,
26770b57cec5SDimitry Andric                                    FunctionDecl *&OperatorDelete,
26780b57cec5SDimitry Andric                                    bool Diagnose) {
26790b57cec5SDimitry Andric   // --- Choosing an allocation function ---
26800b57cec5SDimitry Andric   // C++ 5.3.4p8 - 14 & 18
26810b57cec5SDimitry Andric   // 1) If looking in AFS_Global scope for allocation functions, only look in
26820b57cec5SDimitry Andric   //    the global scope. Else, if AFS_Class, only look in the scope of the
26830b57cec5SDimitry Andric   //    allocated class. If AFS_Both, look in both.
26840b57cec5SDimitry Andric   // 2) If an array size is given, look for operator new[], else look for
26850b57cec5SDimitry Andric   //   operator new.
26860b57cec5SDimitry Andric   // 3) The first argument is always size_t. Append the arguments from the
26870b57cec5SDimitry Andric   //   placement form.
26880b57cec5SDimitry Andric 
26890b57cec5SDimitry Andric   SmallVector<Expr*, 8> AllocArgs;
26900b57cec5SDimitry Andric   AllocArgs.reserve((PassAlignment ? 2 : 1) + PlaceArgs.size());
26910b57cec5SDimitry Andric 
26920b57cec5SDimitry Andric   // We don't care about the actual value of these arguments.
26930b57cec5SDimitry Andric   // FIXME: Should the Sema create the expression and embed it in the syntax
26940b57cec5SDimitry Andric   // tree? Or should the consumer just recalculate the value?
26950b57cec5SDimitry Andric   // FIXME: Using a dummy value will interact poorly with attribute enable_if.
269606c3fb27SDimitry Andric   QualType SizeTy = Context.getSizeType();
269706c3fb27SDimitry Andric   unsigned SizeTyWidth = Context.getTypeSize(SizeTy);
269806c3fb27SDimitry Andric   IntegerLiteral Size(Context, llvm::APInt::getZero(SizeTyWidth), SizeTy,
269906c3fb27SDimitry Andric                       SourceLocation());
27000b57cec5SDimitry Andric   AllocArgs.push_back(&Size);
27010b57cec5SDimitry Andric 
27020b57cec5SDimitry Andric   QualType AlignValT = Context.VoidTy;
27030b57cec5SDimitry Andric   if (PassAlignment) {
27040b57cec5SDimitry Andric     DeclareGlobalNewDelete();
27050b57cec5SDimitry Andric     AlignValT = Context.getTypeDeclType(getStdAlignValT());
27060b57cec5SDimitry Andric   }
27070b57cec5SDimitry Andric   CXXScalarValueInitExpr Align(AlignValT, nullptr, SourceLocation());
27080b57cec5SDimitry Andric   if (PassAlignment)
27090b57cec5SDimitry Andric     AllocArgs.push_back(&Align);
27100b57cec5SDimitry Andric 
27110b57cec5SDimitry Andric   AllocArgs.insert(AllocArgs.end(), PlaceArgs.begin(), PlaceArgs.end());
27120b57cec5SDimitry Andric 
27130b57cec5SDimitry Andric   // C++ [expr.new]p8:
27140b57cec5SDimitry Andric   //   If the allocated type is a non-array type, the allocation
27150b57cec5SDimitry Andric   //   function's name is operator new and the deallocation function's
27160b57cec5SDimitry Andric   //   name is operator delete. If the allocated type is an array
27170b57cec5SDimitry Andric   //   type, the allocation function's name is operator new[] and the
27180b57cec5SDimitry Andric   //   deallocation function's name is operator delete[].
27190b57cec5SDimitry Andric   DeclarationName NewName = Context.DeclarationNames.getCXXOperatorName(
27200b57cec5SDimitry Andric       IsArray ? OO_Array_New : OO_New);
27210b57cec5SDimitry Andric 
27220b57cec5SDimitry Andric   QualType AllocElemType = Context.getBaseElementType(AllocType);
27230b57cec5SDimitry Andric 
27240b57cec5SDimitry Andric   // Find the allocation function.
27250b57cec5SDimitry Andric   {
27260b57cec5SDimitry Andric     LookupResult R(*this, NewName, StartLoc, LookupOrdinaryName);
27270b57cec5SDimitry Andric 
27280b57cec5SDimitry Andric     // C++1z [expr.new]p9:
27290b57cec5SDimitry Andric     //   If the new-expression begins with a unary :: operator, the allocation
27300b57cec5SDimitry Andric     //   function's name is looked up in the global scope. Otherwise, if the
27310b57cec5SDimitry Andric     //   allocated type is a class type T or array thereof, the allocation
27320b57cec5SDimitry Andric     //   function's name is looked up in the scope of T.
27330b57cec5SDimitry Andric     if (AllocElemType->isRecordType() && NewScope != AFS_Global)
27340b57cec5SDimitry Andric       LookupQualifiedName(R, AllocElemType->getAsCXXRecordDecl());
27350b57cec5SDimitry Andric 
27360b57cec5SDimitry Andric     // We can see ambiguity here if the allocation function is found in
27370b57cec5SDimitry Andric     // multiple base classes.
27380b57cec5SDimitry Andric     if (R.isAmbiguous())
27390b57cec5SDimitry Andric       return true;
27400b57cec5SDimitry Andric 
27410b57cec5SDimitry Andric     //   If this lookup fails to find the name, or if the allocated type is not
27420b57cec5SDimitry Andric     //   a class type, the allocation function's name is looked up in the
27430b57cec5SDimitry Andric     //   global scope.
27440b57cec5SDimitry Andric     if (R.empty()) {
27450b57cec5SDimitry Andric       if (NewScope == AFS_Class)
27460b57cec5SDimitry Andric         return true;
27470b57cec5SDimitry Andric 
27480b57cec5SDimitry Andric       LookupQualifiedName(R, Context.getTranslationUnitDecl());
27490b57cec5SDimitry Andric     }
27500b57cec5SDimitry Andric 
27510b57cec5SDimitry Andric     if (getLangOpts().OpenCLCPlusPlus && R.empty()) {
27520b57cec5SDimitry Andric       if (PlaceArgs.empty()) {
27530b57cec5SDimitry Andric         Diag(StartLoc, diag::err_openclcxx_not_supported) << "default new";
27540b57cec5SDimitry Andric       } else {
27550b57cec5SDimitry Andric         Diag(StartLoc, diag::err_openclcxx_placement_new);
27560b57cec5SDimitry Andric       }
27570b57cec5SDimitry Andric       return true;
27580b57cec5SDimitry Andric     }
27590b57cec5SDimitry Andric 
27600b57cec5SDimitry Andric     assert(!R.empty() && "implicitly declared allocation functions not found");
27610b57cec5SDimitry Andric     assert(!R.isAmbiguous() && "global allocation functions are ambiguous");
27620b57cec5SDimitry Andric 
27630b57cec5SDimitry Andric     // We do our own custom access checks below.
27640b57cec5SDimitry Andric     R.suppressDiagnostics();
27650b57cec5SDimitry Andric 
27660b57cec5SDimitry Andric     if (resolveAllocationOverload(*this, R, Range, AllocArgs, PassAlignment,
27670b57cec5SDimitry Andric                                   OperatorNew, /*Candidates=*/nullptr,
27680b57cec5SDimitry Andric                                   /*AlignArg=*/nullptr, Diagnose))
27690b57cec5SDimitry Andric       return true;
27700b57cec5SDimitry Andric   }
27710b57cec5SDimitry Andric 
27720b57cec5SDimitry Andric   // We don't need an operator delete if we're running under -fno-exceptions.
27730b57cec5SDimitry Andric   if (!getLangOpts().Exceptions) {
27740b57cec5SDimitry Andric     OperatorDelete = nullptr;
27750b57cec5SDimitry Andric     return false;
27760b57cec5SDimitry Andric   }
27770b57cec5SDimitry Andric 
27780b57cec5SDimitry Andric   // Note, the name of OperatorNew might have been changed from array to
27790b57cec5SDimitry Andric   // non-array by resolveAllocationOverload.
27800b57cec5SDimitry Andric   DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
27810b57cec5SDimitry Andric       OperatorNew->getDeclName().getCXXOverloadedOperator() == OO_Array_New
27820b57cec5SDimitry Andric           ? OO_Array_Delete
27830b57cec5SDimitry Andric           : OO_Delete);
27840b57cec5SDimitry Andric 
27850b57cec5SDimitry Andric   // C++ [expr.new]p19:
27860b57cec5SDimitry Andric   //
27870b57cec5SDimitry Andric   //   If the new-expression begins with a unary :: operator, the
27880b57cec5SDimitry Andric   //   deallocation function's name is looked up in the global
27890b57cec5SDimitry Andric   //   scope. Otherwise, if the allocated type is a class type T or an
27900b57cec5SDimitry Andric   //   array thereof, the deallocation function's name is looked up in
27910b57cec5SDimitry Andric   //   the scope of T. If this lookup fails to find the name, or if
27920b57cec5SDimitry Andric   //   the allocated type is not a class type or array thereof, the
27930b57cec5SDimitry Andric   //   deallocation function's name is looked up in the global scope.
27940b57cec5SDimitry Andric   LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName);
27950b57cec5SDimitry Andric   if (AllocElemType->isRecordType() && DeleteScope != AFS_Global) {
2796a7dea167SDimitry Andric     auto *RD =
2797a7dea167SDimitry Andric         cast<CXXRecordDecl>(AllocElemType->castAs<RecordType>()->getDecl());
27980b57cec5SDimitry Andric     LookupQualifiedName(FoundDelete, RD);
27990b57cec5SDimitry Andric   }
28000b57cec5SDimitry Andric   if (FoundDelete.isAmbiguous())
28010b57cec5SDimitry Andric     return true; // FIXME: clean up expressions?
28020b57cec5SDimitry Andric 
2803e8d8bef9SDimitry Andric   // Filter out any destroying operator deletes. We can't possibly call such a
2804e8d8bef9SDimitry Andric   // function in this context, because we're handling the case where the object
2805e8d8bef9SDimitry Andric   // was not successfully constructed.
2806e8d8bef9SDimitry Andric   // FIXME: This is not covered by the language rules yet.
2807e8d8bef9SDimitry Andric   {
2808e8d8bef9SDimitry Andric     LookupResult::Filter Filter = FoundDelete.makeFilter();
2809e8d8bef9SDimitry Andric     while (Filter.hasNext()) {
2810e8d8bef9SDimitry Andric       auto *FD = dyn_cast<FunctionDecl>(Filter.next()->getUnderlyingDecl());
2811e8d8bef9SDimitry Andric       if (FD && FD->isDestroyingOperatorDelete())
2812e8d8bef9SDimitry Andric         Filter.erase();
2813e8d8bef9SDimitry Andric     }
2814e8d8bef9SDimitry Andric     Filter.done();
2815e8d8bef9SDimitry Andric   }
2816e8d8bef9SDimitry Andric 
28170b57cec5SDimitry Andric   bool FoundGlobalDelete = FoundDelete.empty();
28180b57cec5SDimitry Andric   if (FoundDelete.empty()) {
2819e8d8bef9SDimitry Andric     FoundDelete.clear(LookupOrdinaryName);
2820e8d8bef9SDimitry Andric 
28210b57cec5SDimitry Andric     if (DeleteScope == AFS_Class)
28220b57cec5SDimitry Andric       return true;
28230b57cec5SDimitry Andric 
28240b57cec5SDimitry Andric     DeclareGlobalNewDelete();
28250b57cec5SDimitry Andric     LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl());
28260b57cec5SDimitry Andric   }
28270b57cec5SDimitry Andric 
28280b57cec5SDimitry Andric   FoundDelete.suppressDiagnostics();
28290b57cec5SDimitry Andric 
28300b57cec5SDimitry Andric   SmallVector<std::pair<DeclAccessPair,FunctionDecl*>, 2> Matches;
28310b57cec5SDimitry Andric 
28320b57cec5SDimitry Andric   // Whether we're looking for a placement operator delete is dictated
28330b57cec5SDimitry Andric   // by whether we selected a placement operator new, not by whether
28340b57cec5SDimitry Andric   // we had explicit placement arguments.  This matters for things like
28350b57cec5SDimitry Andric   //   struct A { void *operator new(size_t, int = 0); ... };
28360b57cec5SDimitry Andric   //   A *a = new A()
28370b57cec5SDimitry Andric   //
28380b57cec5SDimitry Andric   // We don't have any definition for what a "placement allocation function"
28390b57cec5SDimitry Andric   // is, but we assume it's any allocation function whose
28400b57cec5SDimitry Andric   // parameter-declaration-clause is anything other than (size_t).
28410b57cec5SDimitry Andric   //
28420b57cec5SDimitry Andric   // FIXME: Should (size_t, std::align_val_t) also be considered non-placement?
28430b57cec5SDimitry Andric   // This affects whether an exception from the constructor of an overaligned
28440b57cec5SDimitry Andric   // type uses the sized or non-sized form of aligned operator delete.
28450b57cec5SDimitry Andric   bool isPlacementNew = !PlaceArgs.empty() || OperatorNew->param_size() != 1 ||
28460b57cec5SDimitry Andric                         OperatorNew->isVariadic();
28470b57cec5SDimitry Andric 
28480b57cec5SDimitry Andric   if (isPlacementNew) {
28490b57cec5SDimitry Andric     // C++ [expr.new]p20:
28500b57cec5SDimitry Andric     //   A declaration of a placement deallocation function matches the
28510b57cec5SDimitry Andric     //   declaration of a placement allocation function if it has the
28520b57cec5SDimitry Andric     //   same number of parameters and, after parameter transformations
28530b57cec5SDimitry Andric     //   (8.3.5), all parameter types except the first are
28540b57cec5SDimitry Andric     //   identical. [...]
28550b57cec5SDimitry Andric     //
28560b57cec5SDimitry Andric     // To perform this comparison, we compute the function type that
28570b57cec5SDimitry Andric     // the deallocation function should have, and use that type both
28580b57cec5SDimitry Andric     // for template argument deduction and for comparison purposes.
28590b57cec5SDimitry Andric     QualType ExpectedFunctionType;
28600b57cec5SDimitry Andric     {
28615ffd83dbSDimitry Andric       auto *Proto = OperatorNew->getType()->castAs<FunctionProtoType>();
28620b57cec5SDimitry Andric 
28630b57cec5SDimitry Andric       SmallVector<QualType, 4> ArgTypes;
28640b57cec5SDimitry Andric       ArgTypes.push_back(Context.VoidPtrTy);
28650b57cec5SDimitry Andric       for (unsigned I = 1, N = Proto->getNumParams(); I < N; ++I)
28660b57cec5SDimitry Andric         ArgTypes.push_back(Proto->getParamType(I));
28670b57cec5SDimitry Andric 
28680b57cec5SDimitry Andric       FunctionProtoType::ExtProtoInfo EPI;
28690b57cec5SDimitry Andric       // FIXME: This is not part of the standard's rule.
28700b57cec5SDimitry Andric       EPI.Variadic = Proto->isVariadic();
28710b57cec5SDimitry Andric 
28720b57cec5SDimitry Andric       ExpectedFunctionType
28730b57cec5SDimitry Andric         = Context.getFunctionType(Context.VoidTy, ArgTypes, EPI);
28740b57cec5SDimitry Andric     }
28750b57cec5SDimitry Andric 
28760b57cec5SDimitry Andric     for (LookupResult::iterator D = FoundDelete.begin(),
28770b57cec5SDimitry Andric                              DEnd = FoundDelete.end();
28780b57cec5SDimitry Andric          D != DEnd; ++D) {
28790b57cec5SDimitry Andric       FunctionDecl *Fn = nullptr;
28800b57cec5SDimitry Andric       if (FunctionTemplateDecl *FnTmpl =
28810b57cec5SDimitry Andric               dyn_cast<FunctionTemplateDecl>((*D)->getUnderlyingDecl())) {
28820b57cec5SDimitry Andric         // Perform template argument deduction to try to match the
28830b57cec5SDimitry Andric         // expected function type.
28840b57cec5SDimitry Andric         TemplateDeductionInfo Info(StartLoc);
28850b57cec5SDimitry Andric         if (DeduceTemplateArguments(FnTmpl, nullptr, ExpectedFunctionType, Fn,
28860b57cec5SDimitry Andric                                     Info))
28870b57cec5SDimitry Andric           continue;
28880b57cec5SDimitry Andric       } else
28890b57cec5SDimitry Andric         Fn = cast<FunctionDecl>((*D)->getUnderlyingDecl());
28900b57cec5SDimitry Andric 
28910b57cec5SDimitry Andric       if (Context.hasSameType(adjustCCAndNoReturn(Fn->getType(),
28920b57cec5SDimitry Andric                                                   ExpectedFunctionType,
28930b57cec5SDimitry Andric                                                   /*AdjustExcpetionSpec*/true),
28940b57cec5SDimitry Andric                               ExpectedFunctionType))
28950b57cec5SDimitry Andric         Matches.push_back(std::make_pair(D.getPair(), Fn));
28960b57cec5SDimitry Andric     }
28970b57cec5SDimitry Andric 
28980b57cec5SDimitry Andric     if (getLangOpts().CUDA)
289981ad6265SDimitry Andric       EraseUnwantedCUDAMatches(getCurFunctionDecl(/*AllowLambda=*/true),
290081ad6265SDimitry Andric                                Matches);
29010b57cec5SDimitry Andric   } else {
29020b57cec5SDimitry Andric     // C++1y [expr.new]p22:
29030b57cec5SDimitry Andric     //   For a non-placement allocation function, the normal deallocation
29040b57cec5SDimitry Andric     //   function lookup is used
29050b57cec5SDimitry Andric     //
29060b57cec5SDimitry Andric     // Per [expr.delete]p10, this lookup prefers a member operator delete
29070b57cec5SDimitry Andric     // without a size_t argument, but prefers a non-member operator delete
29080b57cec5SDimitry Andric     // with a size_t where possible (which it always is in this case).
29090b57cec5SDimitry Andric     llvm::SmallVector<UsualDeallocFnInfo, 4> BestDeallocFns;
29100b57cec5SDimitry Andric     UsualDeallocFnInfo Selected = resolveDeallocationOverload(
29110b57cec5SDimitry Andric         *this, FoundDelete, /*WantSize*/ FoundGlobalDelete,
29120b57cec5SDimitry Andric         /*WantAlign*/ hasNewExtendedAlignment(*this, AllocElemType),
29130b57cec5SDimitry Andric         &BestDeallocFns);
29140b57cec5SDimitry Andric     if (Selected)
29150b57cec5SDimitry Andric       Matches.push_back(std::make_pair(Selected.Found, Selected.FD));
29160b57cec5SDimitry Andric     else {
29170b57cec5SDimitry Andric       // If we failed to select an operator, all remaining functions are viable
29180b57cec5SDimitry Andric       // but ambiguous.
29190b57cec5SDimitry Andric       for (auto Fn : BestDeallocFns)
29200b57cec5SDimitry Andric         Matches.push_back(std::make_pair(Fn.Found, Fn.FD));
29210b57cec5SDimitry Andric     }
29220b57cec5SDimitry Andric   }
29230b57cec5SDimitry Andric 
29240b57cec5SDimitry Andric   // C++ [expr.new]p20:
29250b57cec5SDimitry Andric   //   [...] If the lookup finds a single matching deallocation
29260b57cec5SDimitry Andric   //   function, that function will be called; otherwise, no
29270b57cec5SDimitry Andric   //   deallocation function will be called.
29280b57cec5SDimitry Andric   if (Matches.size() == 1) {
29290b57cec5SDimitry Andric     OperatorDelete = Matches[0].second;
29300b57cec5SDimitry Andric 
29310b57cec5SDimitry Andric     // C++1z [expr.new]p23:
29320b57cec5SDimitry Andric     //   If the lookup finds a usual deallocation function (3.7.4.2)
29330b57cec5SDimitry Andric     //   with a parameter of type std::size_t and that function, considered
29340b57cec5SDimitry Andric     //   as a placement deallocation function, would have been
29350b57cec5SDimitry Andric     //   selected as a match for the allocation function, the program
29360b57cec5SDimitry Andric     //   is ill-formed.
29370b57cec5SDimitry Andric     if (getLangOpts().CPlusPlus11 && isPlacementNew &&
29380b57cec5SDimitry Andric         isNonPlacementDeallocationFunction(*this, OperatorDelete)) {
29390b57cec5SDimitry Andric       UsualDeallocFnInfo Info(*this,
29400b57cec5SDimitry Andric                               DeclAccessPair::make(OperatorDelete, AS_public));
29410b57cec5SDimitry Andric       // Core issue, per mail to core reflector, 2016-10-09:
29420b57cec5SDimitry Andric       //   If this is a member operator delete, and there is a corresponding
29430b57cec5SDimitry Andric       //   non-sized member operator delete, this isn't /really/ a sized
29440b57cec5SDimitry Andric       //   deallocation function, it just happens to have a size_t parameter.
29450b57cec5SDimitry Andric       bool IsSizedDelete = Info.HasSizeT;
29460b57cec5SDimitry Andric       if (IsSizedDelete && !FoundGlobalDelete) {
29470b57cec5SDimitry Andric         auto NonSizedDelete =
29480b57cec5SDimitry Andric             resolveDeallocationOverload(*this, FoundDelete, /*WantSize*/false,
29490b57cec5SDimitry Andric                                         /*WantAlign*/Info.HasAlignValT);
29500b57cec5SDimitry Andric         if (NonSizedDelete && !NonSizedDelete.HasSizeT &&
29510b57cec5SDimitry Andric             NonSizedDelete.HasAlignValT == Info.HasAlignValT)
29520b57cec5SDimitry Andric           IsSizedDelete = false;
29530b57cec5SDimitry Andric       }
29540b57cec5SDimitry Andric 
29550b57cec5SDimitry Andric       if (IsSizedDelete) {
29560b57cec5SDimitry Andric         SourceRange R = PlaceArgs.empty()
29570b57cec5SDimitry Andric                             ? SourceRange()
29580b57cec5SDimitry Andric                             : SourceRange(PlaceArgs.front()->getBeginLoc(),
29590b57cec5SDimitry Andric                                           PlaceArgs.back()->getEndLoc());
29600b57cec5SDimitry Andric         Diag(StartLoc, diag::err_placement_new_non_placement_delete) << R;
29610b57cec5SDimitry Andric         if (!OperatorDelete->isImplicit())
29620b57cec5SDimitry Andric           Diag(OperatorDelete->getLocation(), diag::note_previous_decl)
29630b57cec5SDimitry Andric               << DeleteName;
29640b57cec5SDimitry Andric       }
29650b57cec5SDimitry Andric     }
29660b57cec5SDimitry Andric 
29670b57cec5SDimitry Andric     CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(),
29680b57cec5SDimitry Andric                           Matches[0].first);
29690b57cec5SDimitry Andric   } else if (!Matches.empty()) {
29700b57cec5SDimitry Andric     // We found multiple suitable operators. Per [expr.new]p20, that means we
29710b57cec5SDimitry Andric     // call no 'operator delete' function, but we should at least warn the user.
29720b57cec5SDimitry Andric     // FIXME: Suppress this warning if the construction cannot throw.
29730b57cec5SDimitry Andric     Diag(StartLoc, diag::warn_ambiguous_suitable_delete_function_found)
29740b57cec5SDimitry Andric       << DeleteName << AllocElemType;
29750b57cec5SDimitry Andric 
29760b57cec5SDimitry Andric     for (auto &Match : Matches)
29770b57cec5SDimitry Andric       Diag(Match.second->getLocation(),
29780b57cec5SDimitry Andric            diag::note_member_declared_here) << DeleteName;
29790b57cec5SDimitry Andric   }
29800b57cec5SDimitry Andric 
29810b57cec5SDimitry Andric   return false;
29820b57cec5SDimitry Andric }
29830b57cec5SDimitry Andric 
29840b57cec5SDimitry Andric /// DeclareGlobalNewDelete - Declare the global forms of operator new and
29850b57cec5SDimitry Andric /// delete. These are:
29860b57cec5SDimitry Andric /// @code
29870b57cec5SDimitry Andric ///   // C++03:
29880b57cec5SDimitry Andric ///   void* operator new(std::size_t) throw(std::bad_alloc);
29890b57cec5SDimitry Andric ///   void* operator new[](std::size_t) throw(std::bad_alloc);
29900b57cec5SDimitry Andric ///   void operator delete(void *) throw();
29910b57cec5SDimitry Andric ///   void operator delete[](void *) throw();
29920b57cec5SDimitry Andric ///   // C++11:
29930b57cec5SDimitry Andric ///   void* operator new(std::size_t);
29940b57cec5SDimitry Andric ///   void* operator new[](std::size_t);
29950b57cec5SDimitry Andric ///   void operator delete(void *) noexcept;
29960b57cec5SDimitry Andric ///   void operator delete[](void *) noexcept;
29970b57cec5SDimitry Andric ///   // C++1y:
29980b57cec5SDimitry Andric ///   void* operator new(std::size_t);
29990b57cec5SDimitry Andric ///   void* operator new[](std::size_t);
30000b57cec5SDimitry Andric ///   void operator delete(void *) noexcept;
30010b57cec5SDimitry Andric ///   void operator delete[](void *) noexcept;
30020b57cec5SDimitry Andric ///   void operator delete(void *, std::size_t) noexcept;
30030b57cec5SDimitry Andric ///   void operator delete[](void *, std::size_t) noexcept;
30040b57cec5SDimitry Andric /// @endcode
30050b57cec5SDimitry Andric /// Note that the placement and nothrow forms of new are *not* implicitly
30060b57cec5SDimitry Andric /// declared. Their use requires including \<new\>.
DeclareGlobalNewDelete()30070b57cec5SDimitry Andric void Sema::DeclareGlobalNewDelete() {
30080b57cec5SDimitry Andric   if (GlobalNewDeleteDeclared)
30090b57cec5SDimitry Andric     return;
30100b57cec5SDimitry Andric 
30110b57cec5SDimitry Andric   // The implicitly declared new and delete operators
30120b57cec5SDimitry Andric   // are not supported in OpenCL.
30130b57cec5SDimitry Andric   if (getLangOpts().OpenCLCPlusPlus)
30140b57cec5SDimitry Andric     return;
30150b57cec5SDimitry Andric 
3016bdd1243dSDimitry Andric   // C++ [basic.stc.dynamic.general]p2:
3017bdd1243dSDimitry Andric   //   The library provides default definitions for the global allocation
3018bdd1243dSDimitry Andric   //   and deallocation functions. Some global allocation and deallocation
3019bdd1243dSDimitry Andric   //   functions are replaceable ([new.delete]); these are attached to the
3020bdd1243dSDimitry Andric   //   global module ([module.unit]).
3021bdd1243dSDimitry Andric   if (getLangOpts().CPlusPlusModules && getCurrentModule())
302206c3fb27SDimitry Andric     PushGlobalModuleFragment(SourceLocation());
3023bdd1243dSDimitry Andric 
30240b57cec5SDimitry Andric   // C++ [basic.std.dynamic]p2:
30250b57cec5SDimitry Andric   //   [...] The following allocation and deallocation functions (18.4) are
30260b57cec5SDimitry Andric   //   implicitly declared in global scope in each translation unit of a
30270b57cec5SDimitry Andric   //   program
30280b57cec5SDimitry Andric   //
30290b57cec5SDimitry Andric   //     C++03:
30300b57cec5SDimitry Andric   //     void* operator new(std::size_t) throw(std::bad_alloc);
30310b57cec5SDimitry Andric   //     void* operator new[](std::size_t) throw(std::bad_alloc);
30320b57cec5SDimitry Andric   //     void  operator delete(void*) throw();
30330b57cec5SDimitry Andric   //     void  operator delete[](void*) throw();
30340b57cec5SDimitry Andric   //     C++11:
30350b57cec5SDimitry Andric   //     void* operator new(std::size_t);
30360b57cec5SDimitry Andric   //     void* operator new[](std::size_t);
30370b57cec5SDimitry Andric   //     void  operator delete(void*) noexcept;
30380b57cec5SDimitry Andric   //     void  operator delete[](void*) noexcept;
30390b57cec5SDimitry Andric   //     C++1y:
30400b57cec5SDimitry Andric   //     void* operator new(std::size_t);
30410b57cec5SDimitry Andric   //     void* operator new[](std::size_t);
30420b57cec5SDimitry Andric   //     void  operator delete(void*) noexcept;
30430b57cec5SDimitry Andric   //     void  operator delete[](void*) noexcept;
30440b57cec5SDimitry Andric   //     void  operator delete(void*, std::size_t) noexcept;
30450b57cec5SDimitry Andric   //     void  operator delete[](void*, std::size_t) noexcept;
30460b57cec5SDimitry Andric   //
30470b57cec5SDimitry Andric   //   These implicit declarations introduce only the function names operator
30480b57cec5SDimitry Andric   //   new, operator new[], operator delete, operator delete[].
30490b57cec5SDimitry Andric   //
30500b57cec5SDimitry Andric   // Here, we need to refer to std::bad_alloc, so we will implicitly declare
30510b57cec5SDimitry Andric   // "std" or "bad_alloc" as necessary to form the exception specification.
30520b57cec5SDimitry Andric   // However, we do not make these implicit declarations visible to name
30530b57cec5SDimitry Andric   // lookup.
30540b57cec5SDimitry Andric   if (!StdBadAlloc && !getLangOpts().CPlusPlus11) {
30550b57cec5SDimitry Andric     // The "std::bad_alloc" class has not yet been declared, so build it
30560b57cec5SDimitry Andric     // implicitly.
30575f757f3fSDimitry Andric     StdBadAlloc = CXXRecordDecl::Create(
30585f757f3fSDimitry Andric         Context, TagTypeKind::Class, getOrCreateStdNamespace(),
30590b57cec5SDimitry Andric         SourceLocation(), SourceLocation(),
30605f757f3fSDimitry Andric         &PP.getIdentifierTable().get("bad_alloc"), nullptr);
30610b57cec5SDimitry Andric     getStdBadAlloc()->setImplicit(true);
3062bdd1243dSDimitry Andric 
3063bdd1243dSDimitry Andric     // The implicitly declared "std::bad_alloc" should live in global module
3064bdd1243dSDimitry Andric     // fragment.
306506c3fb27SDimitry Andric     if (TheGlobalModuleFragment) {
3066bdd1243dSDimitry Andric       getStdBadAlloc()->setModuleOwnershipKind(
3067bdd1243dSDimitry Andric           Decl::ModuleOwnershipKind::ReachableWhenImported);
306806c3fb27SDimitry Andric       getStdBadAlloc()->setLocalOwningModule(TheGlobalModuleFragment);
3069bdd1243dSDimitry Andric     }
30700b57cec5SDimitry Andric   }
30710b57cec5SDimitry Andric   if (!StdAlignValT && getLangOpts().AlignedAllocation) {
30720b57cec5SDimitry Andric     // The "std::align_val_t" enum class has not yet been declared, so build it
30730b57cec5SDimitry Andric     // implicitly.
30740b57cec5SDimitry Andric     auto *AlignValT = EnumDecl::Create(
30750b57cec5SDimitry Andric         Context, getOrCreateStdNamespace(), SourceLocation(), SourceLocation(),
30760b57cec5SDimitry Andric         &PP.getIdentifierTable().get("align_val_t"), nullptr, true, true, true);
3077bdd1243dSDimitry Andric 
3078bdd1243dSDimitry Andric     // The implicitly declared "std::align_val_t" should live in global module
3079bdd1243dSDimitry Andric     // fragment.
308006c3fb27SDimitry Andric     if (TheGlobalModuleFragment) {
3081bdd1243dSDimitry Andric       AlignValT->setModuleOwnershipKind(
3082bdd1243dSDimitry Andric           Decl::ModuleOwnershipKind::ReachableWhenImported);
308306c3fb27SDimitry Andric       AlignValT->setLocalOwningModule(TheGlobalModuleFragment);
3084bdd1243dSDimitry Andric     }
3085bdd1243dSDimitry Andric 
30860b57cec5SDimitry Andric     AlignValT->setIntegerType(Context.getSizeType());
30870b57cec5SDimitry Andric     AlignValT->setPromotionType(Context.getSizeType());
30880b57cec5SDimitry Andric     AlignValT->setImplicit(true);
3089bdd1243dSDimitry Andric 
30900b57cec5SDimitry Andric     StdAlignValT = AlignValT;
30910b57cec5SDimitry Andric   }
30920b57cec5SDimitry Andric 
30930b57cec5SDimitry Andric   GlobalNewDeleteDeclared = true;
30940b57cec5SDimitry Andric 
30950b57cec5SDimitry Andric   QualType VoidPtr = Context.getPointerType(Context.VoidTy);
30960b57cec5SDimitry Andric   QualType SizeT = Context.getSizeType();
30970b57cec5SDimitry Andric 
30980b57cec5SDimitry Andric   auto DeclareGlobalAllocationFunctions = [&](OverloadedOperatorKind Kind,
30990b57cec5SDimitry Andric                                               QualType Return, QualType Param) {
31000b57cec5SDimitry Andric     llvm::SmallVector<QualType, 3> Params;
31010b57cec5SDimitry Andric     Params.push_back(Param);
31020b57cec5SDimitry Andric 
31030b57cec5SDimitry Andric     // Create up to four variants of the function (sized/aligned).
31040b57cec5SDimitry Andric     bool HasSizedVariant = getLangOpts().SizedDeallocation &&
31050b57cec5SDimitry Andric                            (Kind == OO_Delete || Kind == OO_Array_Delete);
31060b57cec5SDimitry Andric     bool HasAlignedVariant = getLangOpts().AlignedAllocation;
31070b57cec5SDimitry Andric 
31080b57cec5SDimitry Andric     int NumSizeVariants = (HasSizedVariant ? 2 : 1);
31090b57cec5SDimitry Andric     int NumAlignVariants = (HasAlignedVariant ? 2 : 1);
31100b57cec5SDimitry Andric     for (int Sized = 0; Sized < NumSizeVariants; ++Sized) {
31110b57cec5SDimitry Andric       if (Sized)
31120b57cec5SDimitry Andric         Params.push_back(SizeT);
31130b57cec5SDimitry Andric 
31140b57cec5SDimitry Andric       for (int Aligned = 0; Aligned < NumAlignVariants; ++Aligned) {
31150b57cec5SDimitry Andric         if (Aligned)
31160b57cec5SDimitry Andric           Params.push_back(Context.getTypeDeclType(getStdAlignValT()));
31170b57cec5SDimitry Andric 
31180b57cec5SDimitry Andric         DeclareGlobalAllocationFunction(
31190b57cec5SDimitry Andric             Context.DeclarationNames.getCXXOperatorName(Kind), Return, Params);
31200b57cec5SDimitry Andric 
31210b57cec5SDimitry Andric         if (Aligned)
31220b57cec5SDimitry Andric           Params.pop_back();
31230b57cec5SDimitry Andric       }
31240b57cec5SDimitry Andric     }
31250b57cec5SDimitry Andric   };
31260b57cec5SDimitry Andric 
31270b57cec5SDimitry Andric   DeclareGlobalAllocationFunctions(OO_New, VoidPtr, SizeT);
31280b57cec5SDimitry Andric   DeclareGlobalAllocationFunctions(OO_Array_New, VoidPtr, SizeT);
31290b57cec5SDimitry Andric   DeclareGlobalAllocationFunctions(OO_Delete, Context.VoidTy, VoidPtr);
31300b57cec5SDimitry Andric   DeclareGlobalAllocationFunctions(OO_Array_Delete, Context.VoidTy, VoidPtr);
3131bdd1243dSDimitry Andric 
3132bdd1243dSDimitry Andric   if (getLangOpts().CPlusPlusModules && getCurrentModule())
3133bdd1243dSDimitry Andric     PopGlobalModuleFragment();
31340b57cec5SDimitry Andric }
31350b57cec5SDimitry Andric 
31360b57cec5SDimitry Andric /// DeclareGlobalAllocationFunction - Declares a single implicit global
31370b57cec5SDimitry Andric /// allocation function if it doesn't already exist.
DeclareGlobalAllocationFunction(DeclarationName Name,QualType Return,ArrayRef<QualType> Params)31380b57cec5SDimitry Andric void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
31390b57cec5SDimitry Andric                                            QualType Return,
31400b57cec5SDimitry Andric                                            ArrayRef<QualType> Params) {
31410b57cec5SDimitry Andric   DeclContext *GlobalCtx = Context.getTranslationUnitDecl();
31420b57cec5SDimitry Andric 
31430b57cec5SDimitry Andric   // Check if this function is already declared.
31440b57cec5SDimitry Andric   DeclContext::lookup_result R = GlobalCtx->lookup(Name);
31450b57cec5SDimitry Andric   for (DeclContext::lookup_iterator Alloc = R.begin(), AllocEnd = R.end();
31460b57cec5SDimitry Andric        Alloc != AllocEnd; ++Alloc) {
31470b57cec5SDimitry Andric     // Only look at non-template functions, as it is the predefined,
31480b57cec5SDimitry Andric     // non-templated allocation function we are trying to declare here.
31490b57cec5SDimitry Andric     if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*Alloc)) {
31500b57cec5SDimitry Andric       if (Func->getNumParams() == Params.size()) {
31510b57cec5SDimitry Andric         llvm::SmallVector<QualType, 3> FuncParams;
31520b57cec5SDimitry Andric         for (auto *P : Func->parameters())
31530b57cec5SDimitry Andric           FuncParams.push_back(
31540b57cec5SDimitry Andric               Context.getCanonicalType(P->getType().getUnqualifiedType()));
3155bdd1243dSDimitry Andric         if (llvm::ArrayRef(FuncParams) == Params) {
31560b57cec5SDimitry Andric           // Make the function visible to name lookup, even if we found it in
31570b57cec5SDimitry Andric           // an unimported module. It either is an implicitly-declared global
31580b57cec5SDimitry Andric           // allocation function, or is suppressing that function.
31590b57cec5SDimitry Andric           Func->setVisibleDespiteOwningModule();
31600b57cec5SDimitry Andric           return;
31610b57cec5SDimitry Andric         }
31620b57cec5SDimitry Andric       }
31630b57cec5SDimitry Andric     }
31640b57cec5SDimitry Andric   }
31650b57cec5SDimitry Andric 
31660b57cec5SDimitry Andric   FunctionProtoType::ExtProtoInfo EPI(Context.getDefaultCallingConvention(
31670b57cec5SDimitry Andric       /*IsVariadic=*/false, /*IsCXXMethod=*/false, /*IsBuiltin=*/true));
31680b57cec5SDimitry Andric 
31690b57cec5SDimitry Andric   QualType BadAllocType;
31700b57cec5SDimitry Andric   bool HasBadAllocExceptionSpec
31710b57cec5SDimitry Andric     = (Name.getCXXOverloadedOperator() == OO_New ||
31720b57cec5SDimitry Andric        Name.getCXXOverloadedOperator() == OO_Array_New);
31730b57cec5SDimitry Andric   if (HasBadAllocExceptionSpec) {
31740b57cec5SDimitry Andric     if (!getLangOpts().CPlusPlus11) {
31750b57cec5SDimitry Andric       BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
31760b57cec5SDimitry Andric       assert(StdBadAlloc && "Must have std::bad_alloc declared");
31770b57cec5SDimitry Andric       EPI.ExceptionSpec.Type = EST_Dynamic;
3178bdd1243dSDimitry Andric       EPI.ExceptionSpec.Exceptions = llvm::ArrayRef(BadAllocType);
31790b57cec5SDimitry Andric     }
3180349cc55cSDimitry Andric     if (getLangOpts().NewInfallible) {
3181349cc55cSDimitry Andric       EPI.ExceptionSpec.Type = EST_DynamicNone;
3182349cc55cSDimitry Andric     }
31830b57cec5SDimitry Andric   } else {
31840b57cec5SDimitry Andric     EPI.ExceptionSpec =
31850b57cec5SDimitry Andric         getLangOpts().CPlusPlus11 ? EST_BasicNoexcept : EST_DynamicNone;
31860b57cec5SDimitry Andric   }
31870b57cec5SDimitry Andric 
31880b57cec5SDimitry Andric   auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) {
31890b57cec5SDimitry Andric     QualType FnType = Context.getFunctionType(Return, Params, EPI);
31900b57cec5SDimitry Andric     FunctionDecl *Alloc = FunctionDecl::Create(
3191349cc55cSDimitry Andric         Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, FnType,
3192349cc55cSDimitry Andric         /*TInfo=*/nullptr, SC_None, getCurFPFeatures().isFPConstrained(), false,
3193349cc55cSDimitry Andric         true);
31940b57cec5SDimitry Andric     Alloc->setImplicit();
31950b57cec5SDimitry Andric     // Global allocation functions should always be visible.
31960b57cec5SDimitry Andric     Alloc->setVisibleDespiteOwningModule();
31970b57cec5SDimitry Andric 
319806c3fb27SDimitry Andric     if (HasBadAllocExceptionSpec && getLangOpts().NewInfallible &&
319906c3fb27SDimitry Andric         !getLangOpts().CheckNew)
3200349cc55cSDimitry Andric       Alloc->addAttr(
3201349cc55cSDimitry Andric           ReturnsNonNullAttr::CreateImplicit(Context, Alloc->getLocation()));
3202349cc55cSDimitry Andric 
3203bdd1243dSDimitry Andric     // C++ [basic.stc.dynamic.general]p2:
3204bdd1243dSDimitry Andric     //   The library provides default definitions for the global allocation
3205bdd1243dSDimitry Andric     //   and deallocation functions. Some global allocation and deallocation
3206bdd1243dSDimitry Andric     //   functions are replaceable ([new.delete]); these are attached to the
3207bdd1243dSDimitry Andric     //   global module ([module.unit]).
3208bdd1243dSDimitry Andric     //
3209bdd1243dSDimitry Andric     // In the language wording, these functions are attched to the global
3210bdd1243dSDimitry Andric     // module all the time. But in the implementation, the global module
3211bdd1243dSDimitry Andric     // is only meaningful when we're in a module unit. So here we attach
3212bdd1243dSDimitry Andric     // these allocation functions to global module conditionally.
321306c3fb27SDimitry Andric     if (TheGlobalModuleFragment) {
3214bdd1243dSDimitry Andric       Alloc->setModuleOwnershipKind(
3215bdd1243dSDimitry Andric           Decl::ModuleOwnershipKind::ReachableWhenImported);
321606c3fb27SDimitry Andric       Alloc->setLocalOwningModule(TheGlobalModuleFragment);
3217bdd1243dSDimitry Andric     }
3218bdd1243dSDimitry Andric 
32197a6dacacSDimitry Andric     if (LangOpts.hasGlobalAllocationFunctionVisibility())
32200b57cec5SDimitry Andric       Alloc->addAttr(VisibilityAttr::CreateImplicit(
32217a6dacacSDimitry Andric           Context, LangOpts.hasHiddenGlobalAllocationFunctionVisibility()
32220b57cec5SDimitry Andric                        ? VisibilityAttr::Hidden
32237a6dacacSDimitry Andric                    : LangOpts.hasProtectedGlobalAllocationFunctionVisibility()
32247a6dacacSDimitry Andric                        ? VisibilityAttr::Protected
32250b57cec5SDimitry Andric                        : VisibilityAttr::Default));
32260b57cec5SDimitry Andric 
32270b57cec5SDimitry Andric     llvm::SmallVector<ParmVarDecl *, 3> ParamDecls;
32280b57cec5SDimitry Andric     for (QualType T : Params) {
32290b57cec5SDimitry Andric       ParamDecls.push_back(ParmVarDecl::Create(
32300b57cec5SDimitry Andric           Context, Alloc, SourceLocation(), SourceLocation(), nullptr, T,
32310b57cec5SDimitry Andric           /*TInfo=*/nullptr, SC_None, nullptr));
32320b57cec5SDimitry Andric       ParamDecls.back()->setImplicit();
32330b57cec5SDimitry Andric     }
32340b57cec5SDimitry Andric     Alloc->setParams(ParamDecls);
32350b57cec5SDimitry Andric     if (ExtraAttr)
32360b57cec5SDimitry Andric       Alloc->addAttr(ExtraAttr);
32375ffd83dbSDimitry Andric     AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction(Alloc);
32380b57cec5SDimitry Andric     Context.getTranslationUnitDecl()->addDecl(Alloc);
32390b57cec5SDimitry Andric     IdResolver.tryAddTopLevelDecl(Alloc, Name);
32400b57cec5SDimitry Andric   };
32410b57cec5SDimitry Andric 
32420b57cec5SDimitry Andric   if (!LangOpts.CUDA)
32430b57cec5SDimitry Andric     CreateAllocationFunctionDecl(nullptr);
32440b57cec5SDimitry Andric   else {
32450b57cec5SDimitry Andric     // Host and device get their own declaration so each can be
32460b57cec5SDimitry Andric     // defined or re-declared independently.
32470b57cec5SDimitry Andric     CreateAllocationFunctionDecl(CUDAHostAttr::CreateImplicit(Context));
32480b57cec5SDimitry Andric     CreateAllocationFunctionDecl(CUDADeviceAttr::CreateImplicit(Context));
32490b57cec5SDimitry Andric   }
32500b57cec5SDimitry Andric }
32510b57cec5SDimitry Andric 
FindUsualDeallocationFunction(SourceLocation StartLoc,bool CanProvideSize,bool Overaligned,DeclarationName Name)32520b57cec5SDimitry Andric FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc,
32530b57cec5SDimitry Andric                                                   bool CanProvideSize,
32540b57cec5SDimitry Andric                                                   bool Overaligned,
32550b57cec5SDimitry Andric                                                   DeclarationName Name) {
32560b57cec5SDimitry Andric   DeclareGlobalNewDelete();
32570b57cec5SDimitry Andric 
32580b57cec5SDimitry Andric   LookupResult FoundDelete(*this, Name, StartLoc, LookupOrdinaryName);
32590b57cec5SDimitry Andric   LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl());
32600b57cec5SDimitry Andric 
32610b57cec5SDimitry Andric   // FIXME: It's possible for this to result in ambiguity, through a
32620b57cec5SDimitry Andric   // user-declared variadic operator delete or the enable_if attribute. We
32630b57cec5SDimitry Andric   // should probably not consider those cases to be usual deallocation
32640b57cec5SDimitry Andric   // functions. But for now we just make an arbitrary choice in that case.
32650b57cec5SDimitry Andric   auto Result = resolveDeallocationOverload(*this, FoundDelete, CanProvideSize,
32660b57cec5SDimitry Andric                                             Overaligned);
32670b57cec5SDimitry Andric   assert(Result.FD && "operator delete missing from global scope?");
32680b57cec5SDimitry Andric   return Result.FD;
32690b57cec5SDimitry Andric }
32700b57cec5SDimitry Andric 
FindDeallocationFunctionForDestructor(SourceLocation Loc,CXXRecordDecl * RD)32710b57cec5SDimitry Andric FunctionDecl *Sema::FindDeallocationFunctionForDestructor(SourceLocation Loc,
32720b57cec5SDimitry Andric                                                           CXXRecordDecl *RD) {
32730b57cec5SDimitry Andric   DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Delete);
32740b57cec5SDimitry Andric 
32750b57cec5SDimitry Andric   FunctionDecl *OperatorDelete = nullptr;
32760b57cec5SDimitry Andric   if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
32770b57cec5SDimitry Andric     return nullptr;
32780b57cec5SDimitry Andric   if (OperatorDelete)
32790b57cec5SDimitry Andric     return OperatorDelete;
32800b57cec5SDimitry Andric 
32810b57cec5SDimitry Andric   // If there's no class-specific operator delete, look up the global
32820b57cec5SDimitry Andric   // non-array delete.
32830b57cec5SDimitry Andric   return FindUsualDeallocationFunction(
32840b57cec5SDimitry Andric       Loc, true, hasNewExtendedAlignment(*this, Context.getRecordType(RD)),
32850b57cec5SDimitry Andric       Name);
32860b57cec5SDimitry Andric }
32870b57cec5SDimitry Andric 
FindDeallocationFunction(SourceLocation StartLoc,CXXRecordDecl * RD,DeclarationName Name,FunctionDecl * & Operator,bool Diagnose,bool WantSize,bool WantAligned)32880b57cec5SDimitry Andric bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
32890b57cec5SDimitry Andric                                     DeclarationName Name,
3290bdd1243dSDimitry Andric                                     FunctionDecl *&Operator, bool Diagnose,
3291bdd1243dSDimitry Andric                                     bool WantSize, bool WantAligned) {
32920b57cec5SDimitry Andric   LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName);
32930b57cec5SDimitry Andric   // Try to find operator delete/operator delete[] in class scope.
32940b57cec5SDimitry Andric   LookupQualifiedName(Found, RD);
32950b57cec5SDimitry Andric 
32960b57cec5SDimitry Andric   if (Found.isAmbiguous())
32970b57cec5SDimitry Andric     return true;
32980b57cec5SDimitry Andric 
32990b57cec5SDimitry Andric   Found.suppressDiagnostics();
33000b57cec5SDimitry Andric 
3301bdd1243dSDimitry Andric   bool Overaligned =
3302bdd1243dSDimitry Andric       WantAligned || hasNewExtendedAlignment(*this, Context.getRecordType(RD));
33030b57cec5SDimitry Andric 
33040b57cec5SDimitry Andric   // C++17 [expr.delete]p10:
33050b57cec5SDimitry Andric   //   If the deallocation functions have class scope, the one without a
33060b57cec5SDimitry Andric   //   parameter of type std::size_t is selected.
33070b57cec5SDimitry Andric   llvm::SmallVector<UsualDeallocFnInfo, 4> Matches;
3308bdd1243dSDimitry Andric   resolveDeallocationOverload(*this, Found, /*WantSize*/ WantSize,
33090b57cec5SDimitry Andric                               /*WantAlign*/ Overaligned, &Matches);
33100b57cec5SDimitry Andric 
33110b57cec5SDimitry Andric   // If we could find an overload, use it.
33120b57cec5SDimitry Andric   if (Matches.size() == 1) {
33130b57cec5SDimitry Andric     Operator = cast<CXXMethodDecl>(Matches[0].FD);
33140b57cec5SDimitry Andric 
33150b57cec5SDimitry Andric     // FIXME: DiagnoseUseOfDecl?
33160b57cec5SDimitry Andric     if (Operator->isDeleted()) {
33170b57cec5SDimitry Andric       if (Diagnose) {
33180b57cec5SDimitry Andric         Diag(StartLoc, diag::err_deleted_function_use);
33190b57cec5SDimitry Andric         NoteDeletedFunction(Operator);
33200b57cec5SDimitry Andric       }
33210b57cec5SDimitry Andric       return true;
33220b57cec5SDimitry Andric     }
33230b57cec5SDimitry Andric 
33240b57cec5SDimitry Andric     if (CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
33250b57cec5SDimitry Andric                               Matches[0].Found, Diagnose) == AR_inaccessible)
33260b57cec5SDimitry Andric       return true;
33270b57cec5SDimitry Andric 
33280b57cec5SDimitry Andric     return false;
33290b57cec5SDimitry Andric   }
33300b57cec5SDimitry Andric 
33310b57cec5SDimitry Andric   // We found multiple suitable operators; complain about the ambiguity.
33320b57cec5SDimitry Andric   // FIXME: The standard doesn't say to do this; it appears that the intent
33330b57cec5SDimitry Andric   // is that this should never happen.
33340b57cec5SDimitry Andric   if (!Matches.empty()) {
33350b57cec5SDimitry Andric     if (Diagnose) {
33360b57cec5SDimitry Andric       Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
33370b57cec5SDimitry Andric         << Name << RD;
33380b57cec5SDimitry Andric       for (auto &Match : Matches)
33390b57cec5SDimitry Andric         Diag(Match.FD->getLocation(), diag::note_member_declared_here) << Name;
33400b57cec5SDimitry Andric     }
33410b57cec5SDimitry Andric     return true;
33420b57cec5SDimitry Andric   }
33430b57cec5SDimitry Andric 
33440b57cec5SDimitry Andric   // We did find operator delete/operator delete[] declarations, but
33450b57cec5SDimitry Andric   // none of them were suitable.
33460b57cec5SDimitry Andric   if (!Found.empty()) {
33470b57cec5SDimitry Andric     if (Diagnose) {
33480b57cec5SDimitry Andric       Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
33490b57cec5SDimitry Andric         << Name << RD;
33500b57cec5SDimitry Andric 
33510b57cec5SDimitry Andric       for (NamedDecl *D : Found)
33520b57cec5SDimitry Andric         Diag(D->getUnderlyingDecl()->getLocation(),
33530b57cec5SDimitry Andric              diag::note_member_declared_here) << Name;
33540b57cec5SDimitry Andric     }
33550b57cec5SDimitry Andric     return true;
33560b57cec5SDimitry Andric   }
33570b57cec5SDimitry Andric 
33580b57cec5SDimitry Andric   Operator = nullptr;
33590b57cec5SDimitry Andric   return false;
33600b57cec5SDimitry Andric }
33610b57cec5SDimitry Andric 
33620b57cec5SDimitry Andric namespace {
33630b57cec5SDimitry Andric /// Checks whether delete-expression, and new-expression used for
33640b57cec5SDimitry Andric ///  initializing deletee have the same array form.
33650b57cec5SDimitry Andric class MismatchingNewDeleteDetector {
33660b57cec5SDimitry Andric public:
33670b57cec5SDimitry Andric   enum MismatchResult {
33680b57cec5SDimitry Andric     /// Indicates that there is no mismatch or a mismatch cannot be proven.
33690b57cec5SDimitry Andric     NoMismatch,
33700b57cec5SDimitry Andric     /// Indicates that variable is initialized with mismatching form of \a new.
33710b57cec5SDimitry Andric     VarInitMismatches,
33720b57cec5SDimitry Andric     /// Indicates that member is initialized with mismatching form of \a new.
33730b57cec5SDimitry Andric     MemberInitMismatches,
33740b57cec5SDimitry Andric     /// Indicates that 1 or more constructors' definitions could not been
33750b57cec5SDimitry Andric     /// analyzed, and they will be checked again at the end of translation unit.
33760b57cec5SDimitry Andric     AnalyzeLater
33770b57cec5SDimitry Andric   };
33780b57cec5SDimitry Andric 
33790b57cec5SDimitry Andric   /// \param EndOfTU True, if this is the final analysis at the end of
33800b57cec5SDimitry Andric   /// translation unit. False, if this is the initial analysis at the point
33810b57cec5SDimitry Andric   /// delete-expression was encountered.
MismatchingNewDeleteDetector(bool EndOfTU)33820b57cec5SDimitry Andric   explicit MismatchingNewDeleteDetector(bool EndOfTU)
33830b57cec5SDimitry Andric       : Field(nullptr), IsArrayForm(false), EndOfTU(EndOfTU),
33840b57cec5SDimitry Andric         HasUndefinedConstructors(false) {}
33850b57cec5SDimitry Andric 
33860b57cec5SDimitry Andric   /// Checks whether pointee of a delete-expression is initialized with
33870b57cec5SDimitry Andric   /// matching form of new-expression.
33880b57cec5SDimitry Andric   ///
33890b57cec5SDimitry Andric   /// If return value is \c VarInitMismatches or \c MemberInitMismatches at the
33900b57cec5SDimitry Andric   /// point where delete-expression is encountered, then a warning will be
33910b57cec5SDimitry Andric   /// issued immediately. If return value is \c AnalyzeLater at the point where
33920b57cec5SDimitry Andric   /// delete-expression is seen, then member will be analyzed at the end of
33930b57cec5SDimitry Andric   /// translation unit. \c AnalyzeLater is returned iff at least one constructor
33940b57cec5SDimitry Andric   /// couldn't be analyzed. If at least one constructor initializes the member
33950b57cec5SDimitry Andric   /// with matching type of new, the return value is \c NoMismatch.
33960b57cec5SDimitry Andric   MismatchResult analyzeDeleteExpr(const CXXDeleteExpr *DE);
33970b57cec5SDimitry Andric   /// Analyzes a class member.
33980b57cec5SDimitry Andric   /// \param Field Class member to analyze.
33990b57cec5SDimitry Andric   /// \param DeleteWasArrayForm Array form-ness of the delete-expression used
34000b57cec5SDimitry Andric   /// for deleting the \p Field.
34010b57cec5SDimitry Andric   MismatchResult analyzeField(FieldDecl *Field, bool DeleteWasArrayForm);
34020b57cec5SDimitry Andric   FieldDecl *Field;
34030b57cec5SDimitry Andric   /// List of mismatching new-expressions used for initialization of the pointee
34040b57cec5SDimitry Andric   llvm::SmallVector<const CXXNewExpr *, 4> NewExprs;
34050b57cec5SDimitry Andric   /// Indicates whether delete-expression was in array form.
34060b57cec5SDimitry Andric   bool IsArrayForm;
34070b57cec5SDimitry Andric 
34080b57cec5SDimitry Andric private:
34090b57cec5SDimitry Andric   const bool EndOfTU;
34100b57cec5SDimitry Andric   /// Indicates that there is at least one constructor without body.
34110b57cec5SDimitry Andric   bool HasUndefinedConstructors;
34120b57cec5SDimitry Andric   /// Returns \c CXXNewExpr from given initialization expression.
34130b57cec5SDimitry Andric   /// \param E Expression used for initializing pointee in delete-expression.
34140b57cec5SDimitry Andric   /// E can be a single-element \c InitListExpr consisting of new-expression.
34150b57cec5SDimitry Andric   const CXXNewExpr *getNewExprFromInitListOrExpr(const Expr *E);
34160b57cec5SDimitry Andric   /// Returns whether member is initialized with mismatching form of
34170b57cec5SDimitry Andric   /// \c new either by the member initializer or in-class initialization.
34180b57cec5SDimitry Andric   ///
34190b57cec5SDimitry Andric   /// If bodies of all constructors are not visible at the end of translation
34200b57cec5SDimitry Andric   /// unit or at least one constructor initializes member with the matching
34210b57cec5SDimitry Andric   /// form of \c new, mismatch cannot be proven, and this function will return
34220b57cec5SDimitry Andric   /// \c NoMismatch.
34230b57cec5SDimitry Andric   MismatchResult analyzeMemberExpr(const MemberExpr *ME);
34240b57cec5SDimitry Andric   /// Returns whether variable is initialized with mismatching form of
34250b57cec5SDimitry Andric   /// \c new.
34260b57cec5SDimitry Andric   ///
34270b57cec5SDimitry Andric   /// If variable is initialized with matching form of \c new or variable is not
34280b57cec5SDimitry Andric   /// initialized with a \c new expression, this function will return true.
34290b57cec5SDimitry Andric   /// If variable is initialized with mismatching form of \c new, returns false.
34300b57cec5SDimitry Andric   /// \param D Variable to analyze.
34310b57cec5SDimitry Andric   bool hasMatchingVarInit(const DeclRefExpr *D);
34320b57cec5SDimitry Andric   /// Checks whether the constructor initializes pointee with mismatching
34330b57cec5SDimitry Andric   /// form of \c new.
34340b57cec5SDimitry Andric   ///
34350b57cec5SDimitry Andric   /// Returns true, if member is initialized with matching form of \c new in
34360b57cec5SDimitry Andric   /// member initializer list. Returns false, if member is initialized with the
34370b57cec5SDimitry Andric   /// matching form of \c new in this constructor's initializer or given
34380b57cec5SDimitry Andric   /// constructor isn't defined at the point where delete-expression is seen, or
34390b57cec5SDimitry Andric   /// member isn't initialized by the constructor.
34400b57cec5SDimitry Andric   bool hasMatchingNewInCtor(const CXXConstructorDecl *CD);
34410b57cec5SDimitry Andric   /// Checks whether member is initialized with matching form of
34420b57cec5SDimitry Andric   /// \c new in member initializer list.
34430b57cec5SDimitry Andric   bool hasMatchingNewInCtorInit(const CXXCtorInitializer *CI);
34440b57cec5SDimitry Andric   /// Checks whether member is initialized with mismatching form of \c new by
34450b57cec5SDimitry Andric   /// in-class initializer.
34460b57cec5SDimitry Andric   MismatchResult analyzeInClassInitializer();
34470b57cec5SDimitry Andric };
34480b57cec5SDimitry Andric }
34490b57cec5SDimitry Andric 
34500b57cec5SDimitry Andric MismatchingNewDeleteDetector::MismatchResult
analyzeDeleteExpr(const CXXDeleteExpr * DE)34510b57cec5SDimitry Andric MismatchingNewDeleteDetector::analyzeDeleteExpr(const CXXDeleteExpr *DE) {
34520b57cec5SDimitry Andric   NewExprs.clear();
34530b57cec5SDimitry Andric   assert(DE && "Expected delete-expression");
34540b57cec5SDimitry Andric   IsArrayForm = DE->isArrayForm();
34550b57cec5SDimitry Andric   const Expr *E = DE->getArgument()->IgnoreParenImpCasts();
34560b57cec5SDimitry Andric   if (const MemberExpr *ME = dyn_cast<const MemberExpr>(E)) {
34570b57cec5SDimitry Andric     return analyzeMemberExpr(ME);
34580b57cec5SDimitry Andric   } else if (const DeclRefExpr *D = dyn_cast<const DeclRefExpr>(E)) {
34590b57cec5SDimitry Andric     if (!hasMatchingVarInit(D))
34600b57cec5SDimitry Andric       return VarInitMismatches;
34610b57cec5SDimitry Andric   }
34620b57cec5SDimitry Andric   return NoMismatch;
34630b57cec5SDimitry Andric }
34640b57cec5SDimitry Andric 
34650b57cec5SDimitry Andric const CXXNewExpr *
getNewExprFromInitListOrExpr(const Expr * E)34660b57cec5SDimitry Andric MismatchingNewDeleteDetector::getNewExprFromInitListOrExpr(const Expr *E) {
34670b57cec5SDimitry Andric   assert(E != nullptr && "Expected a valid initializer expression");
34680b57cec5SDimitry Andric   E = E->IgnoreParenImpCasts();
34690b57cec5SDimitry Andric   if (const InitListExpr *ILE = dyn_cast<const InitListExpr>(E)) {
34700b57cec5SDimitry Andric     if (ILE->getNumInits() == 1)
34710b57cec5SDimitry Andric       E = dyn_cast<const CXXNewExpr>(ILE->getInit(0)->IgnoreParenImpCasts());
34720b57cec5SDimitry Andric   }
34730b57cec5SDimitry Andric 
34740b57cec5SDimitry Andric   return dyn_cast_or_null<const CXXNewExpr>(E);
34750b57cec5SDimitry Andric }
34760b57cec5SDimitry Andric 
hasMatchingNewInCtorInit(const CXXCtorInitializer * CI)34770b57cec5SDimitry Andric bool MismatchingNewDeleteDetector::hasMatchingNewInCtorInit(
34780b57cec5SDimitry Andric     const CXXCtorInitializer *CI) {
34790b57cec5SDimitry Andric   const CXXNewExpr *NE = nullptr;
34800b57cec5SDimitry Andric   if (Field == CI->getMember() &&
34810b57cec5SDimitry Andric       (NE = getNewExprFromInitListOrExpr(CI->getInit()))) {
34820b57cec5SDimitry Andric     if (NE->isArray() == IsArrayForm)
34830b57cec5SDimitry Andric       return true;
34840b57cec5SDimitry Andric     else
34850b57cec5SDimitry Andric       NewExprs.push_back(NE);
34860b57cec5SDimitry Andric   }
34870b57cec5SDimitry Andric   return false;
34880b57cec5SDimitry Andric }
34890b57cec5SDimitry Andric 
hasMatchingNewInCtor(const CXXConstructorDecl * CD)34900b57cec5SDimitry Andric bool MismatchingNewDeleteDetector::hasMatchingNewInCtor(
34910b57cec5SDimitry Andric     const CXXConstructorDecl *CD) {
34920b57cec5SDimitry Andric   if (CD->isImplicit())
34930b57cec5SDimitry Andric     return false;
34940b57cec5SDimitry Andric   const FunctionDecl *Definition = CD;
34950b57cec5SDimitry Andric   if (!CD->isThisDeclarationADefinition() && !CD->isDefined(Definition)) {
34960b57cec5SDimitry Andric     HasUndefinedConstructors = true;
34970b57cec5SDimitry Andric     return EndOfTU;
34980b57cec5SDimitry Andric   }
34990b57cec5SDimitry Andric   for (const auto *CI : cast<const CXXConstructorDecl>(Definition)->inits()) {
35000b57cec5SDimitry Andric     if (hasMatchingNewInCtorInit(CI))
35010b57cec5SDimitry Andric       return true;
35020b57cec5SDimitry Andric   }
35030b57cec5SDimitry Andric   return false;
35040b57cec5SDimitry Andric }
35050b57cec5SDimitry Andric 
35060b57cec5SDimitry Andric MismatchingNewDeleteDetector::MismatchResult
analyzeInClassInitializer()35070b57cec5SDimitry Andric MismatchingNewDeleteDetector::analyzeInClassInitializer() {
35080b57cec5SDimitry Andric   assert(Field != nullptr && "This should be called only for members");
35090b57cec5SDimitry Andric   const Expr *InitExpr = Field->getInClassInitializer();
35100b57cec5SDimitry Andric   if (!InitExpr)
35110b57cec5SDimitry Andric     return EndOfTU ? NoMismatch : AnalyzeLater;
35120b57cec5SDimitry Andric   if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) {
35130b57cec5SDimitry Andric     if (NE->isArray() != IsArrayForm) {
35140b57cec5SDimitry Andric       NewExprs.push_back(NE);
35150b57cec5SDimitry Andric       return MemberInitMismatches;
35160b57cec5SDimitry Andric     }
35170b57cec5SDimitry Andric   }
35180b57cec5SDimitry Andric   return NoMismatch;
35190b57cec5SDimitry Andric }
35200b57cec5SDimitry Andric 
35210b57cec5SDimitry Andric MismatchingNewDeleteDetector::MismatchResult
analyzeField(FieldDecl * Field,bool DeleteWasArrayForm)35220b57cec5SDimitry Andric MismatchingNewDeleteDetector::analyzeField(FieldDecl *Field,
35230b57cec5SDimitry Andric                                            bool DeleteWasArrayForm) {
35240b57cec5SDimitry Andric   assert(Field != nullptr && "Analysis requires a valid class member.");
35250b57cec5SDimitry Andric   this->Field = Field;
35260b57cec5SDimitry Andric   IsArrayForm = DeleteWasArrayForm;
35270b57cec5SDimitry Andric   const CXXRecordDecl *RD = cast<const CXXRecordDecl>(Field->getParent());
35280b57cec5SDimitry Andric   for (const auto *CD : RD->ctors()) {
35290b57cec5SDimitry Andric     if (hasMatchingNewInCtor(CD))
35300b57cec5SDimitry Andric       return NoMismatch;
35310b57cec5SDimitry Andric   }
35320b57cec5SDimitry Andric   if (HasUndefinedConstructors)
35330b57cec5SDimitry Andric     return EndOfTU ? NoMismatch : AnalyzeLater;
35340b57cec5SDimitry Andric   if (!NewExprs.empty())
35350b57cec5SDimitry Andric     return MemberInitMismatches;
35360b57cec5SDimitry Andric   return Field->hasInClassInitializer() ? analyzeInClassInitializer()
35370b57cec5SDimitry Andric                                         : NoMismatch;
35380b57cec5SDimitry Andric }
35390b57cec5SDimitry Andric 
35400b57cec5SDimitry Andric MismatchingNewDeleteDetector::MismatchResult
analyzeMemberExpr(const MemberExpr * ME)35410b57cec5SDimitry Andric MismatchingNewDeleteDetector::analyzeMemberExpr(const MemberExpr *ME) {
35420b57cec5SDimitry Andric   assert(ME != nullptr && "Expected a member expression");
35430b57cec5SDimitry Andric   if (FieldDecl *F = dyn_cast<FieldDecl>(ME->getMemberDecl()))
35440b57cec5SDimitry Andric     return analyzeField(F, IsArrayForm);
35450b57cec5SDimitry Andric   return NoMismatch;
35460b57cec5SDimitry Andric }
35470b57cec5SDimitry Andric 
hasMatchingVarInit(const DeclRefExpr * D)35480b57cec5SDimitry Andric bool MismatchingNewDeleteDetector::hasMatchingVarInit(const DeclRefExpr *D) {
35490b57cec5SDimitry Andric   const CXXNewExpr *NE = nullptr;
35500b57cec5SDimitry Andric   if (const VarDecl *VD = dyn_cast<const VarDecl>(D->getDecl())) {
35510b57cec5SDimitry Andric     if (VD->hasInit() && (NE = getNewExprFromInitListOrExpr(VD->getInit())) &&
35520b57cec5SDimitry Andric         NE->isArray() != IsArrayForm) {
35530b57cec5SDimitry Andric       NewExprs.push_back(NE);
35540b57cec5SDimitry Andric     }
35550b57cec5SDimitry Andric   }
35560b57cec5SDimitry Andric   return NewExprs.empty();
35570b57cec5SDimitry Andric }
35580b57cec5SDimitry Andric 
35590b57cec5SDimitry Andric static void
DiagnoseMismatchedNewDelete(Sema & SemaRef,SourceLocation DeleteLoc,const MismatchingNewDeleteDetector & Detector)35600b57cec5SDimitry Andric DiagnoseMismatchedNewDelete(Sema &SemaRef, SourceLocation DeleteLoc,
35610b57cec5SDimitry Andric                             const MismatchingNewDeleteDetector &Detector) {
35620b57cec5SDimitry Andric   SourceLocation EndOfDelete = SemaRef.getLocForEndOfToken(DeleteLoc);
35630b57cec5SDimitry Andric   FixItHint H;
35640b57cec5SDimitry Andric   if (!Detector.IsArrayForm)
35650b57cec5SDimitry Andric     H = FixItHint::CreateInsertion(EndOfDelete, "[]");
35660b57cec5SDimitry Andric   else {
35670b57cec5SDimitry Andric     SourceLocation RSquare = Lexer::findLocationAfterToken(
35680b57cec5SDimitry Andric         DeleteLoc, tok::l_square, SemaRef.getSourceManager(),
35690b57cec5SDimitry Andric         SemaRef.getLangOpts(), true);
35700b57cec5SDimitry Andric     if (RSquare.isValid())
35710b57cec5SDimitry Andric       H = FixItHint::CreateRemoval(SourceRange(EndOfDelete, RSquare));
35720b57cec5SDimitry Andric   }
35730b57cec5SDimitry Andric   SemaRef.Diag(DeleteLoc, diag::warn_mismatched_delete_new)
35740b57cec5SDimitry Andric       << Detector.IsArrayForm << H;
35750b57cec5SDimitry Andric 
35760b57cec5SDimitry Andric   for (const auto *NE : Detector.NewExprs)
35770b57cec5SDimitry Andric     SemaRef.Diag(NE->getExprLoc(), diag::note_allocated_here)
35780b57cec5SDimitry Andric         << Detector.IsArrayForm;
35790b57cec5SDimitry Andric }
35800b57cec5SDimitry Andric 
AnalyzeDeleteExprMismatch(const CXXDeleteExpr * DE)35810b57cec5SDimitry Andric void Sema::AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE) {
35820b57cec5SDimitry Andric   if (Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation()))
35830b57cec5SDimitry Andric     return;
35840b57cec5SDimitry Andric   MismatchingNewDeleteDetector Detector(/*EndOfTU=*/false);
35850b57cec5SDimitry Andric   switch (Detector.analyzeDeleteExpr(DE)) {
35860b57cec5SDimitry Andric   case MismatchingNewDeleteDetector::VarInitMismatches:
35870b57cec5SDimitry Andric   case MismatchingNewDeleteDetector::MemberInitMismatches: {
35880b57cec5SDimitry Andric     DiagnoseMismatchedNewDelete(*this, DE->getBeginLoc(), Detector);
35890b57cec5SDimitry Andric     break;
35900b57cec5SDimitry Andric   }
35910b57cec5SDimitry Andric   case MismatchingNewDeleteDetector::AnalyzeLater: {
35920b57cec5SDimitry Andric     DeleteExprs[Detector.Field].push_back(
35930b57cec5SDimitry Andric         std::make_pair(DE->getBeginLoc(), DE->isArrayForm()));
35940b57cec5SDimitry Andric     break;
35950b57cec5SDimitry Andric   }
35960b57cec5SDimitry Andric   case MismatchingNewDeleteDetector::NoMismatch:
35970b57cec5SDimitry Andric     break;
35980b57cec5SDimitry Andric   }
35990b57cec5SDimitry Andric }
36000b57cec5SDimitry Andric 
AnalyzeDeleteExprMismatch(FieldDecl * Field,SourceLocation DeleteLoc,bool DeleteWasArrayForm)36010b57cec5SDimitry Andric void Sema::AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,
36020b57cec5SDimitry Andric                                      bool DeleteWasArrayForm) {
36030b57cec5SDimitry Andric   MismatchingNewDeleteDetector Detector(/*EndOfTU=*/true);
36040b57cec5SDimitry Andric   switch (Detector.analyzeField(Field, DeleteWasArrayForm)) {
36050b57cec5SDimitry Andric   case MismatchingNewDeleteDetector::VarInitMismatches:
36060b57cec5SDimitry Andric     llvm_unreachable("This analysis should have been done for class members.");
36070b57cec5SDimitry Andric   case MismatchingNewDeleteDetector::AnalyzeLater:
36080b57cec5SDimitry Andric     llvm_unreachable("Analysis cannot be postponed any point beyond end of "
36090b57cec5SDimitry Andric                      "translation unit.");
36100b57cec5SDimitry Andric   case MismatchingNewDeleteDetector::MemberInitMismatches:
36110b57cec5SDimitry Andric     DiagnoseMismatchedNewDelete(*this, DeleteLoc, Detector);
36120b57cec5SDimitry Andric     break;
36130b57cec5SDimitry Andric   case MismatchingNewDeleteDetector::NoMismatch:
36140b57cec5SDimitry Andric     break;
36150b57cec5SDimitry Andric   }
36160b57cec5SDimitry Andric }
36170b57cec5SDimitry Andric 
36180b57cec5SDimitry Andric /// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
36190b57cec5SDimitry Andric /// @code ::delete ptr; @endcode
36200b57cec5SDimitry Andric /// or
36210b57cec5SDimitry Andric /// @code delete [] ptr; @endcode
36220b57cec5SDimitry Andric ExprResult
ActOnCXXDelete(SourceLocation StartLoc,bool UseGlobal,bool ArrayForm,Expr * ExE)36230b57cec5SDimitry Andric Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
36240b57cec5SDimitry Andric                      bool ArrayForm, Expr *ExE) {
36250b57cec5SDimitry Andric   // C++ [expr.delete]p1:
36260b57cec5SDimitry Andric   //   The operand shall have a pointer type, or a class type having a single
36270b57cec5SDimitry Andric   //   non-explicit conversion function to a pointer type. The result has type
36280b57cec5SDimitry Andric   //   void.
36290b57cec5SDimitry Andric   //
36300b57cec5SDimitry Andric   // DR599 amends "pointer type" to "pointer to object type" in both cases.
36310b57cec5SDimitry Andric 
36320b57cec5SDimitry Andric   ExprResult Ex = ExE;
36330b57cec5SDimitry Andric   FunctionDecl *OperatorDelete = nullptr;
36340b57cec5SDimitry Andric   bool ArrayFormAsWritten = ArrayForm;
36350b57cec5SDimitry Andric   bool UsualArrayDeleteWantsSize = false;
36360b57cec5SDimitry Andric 
36370b57cec5SDimitry Andric   if (!Ex.get()->isTypeDependent()) {
36380b57cec5SDimitry Andric     // Perform lvalue-to-rvalue cast, if needed.
36390b57cec5SDimitry Andric     Ex = DefaultLvalueConversion(Ex.get());
36400b57cec5SDimitry Andric     if (Ex.isInvalid())
36410b57cec5SDimitry Andric       return ExprError();
36420b57cec5SDimitry Andric 
36430b57cec5SDimitry Andric     QualType Type = Ex.get()->getType();
36440b57cec5SDimitry Andric 
36450b57cec5SDimitry Andric     class DeleteConverter : public ContextualImplicitConverter {
36460b57cec5SDimitry Andric     public:
36470b57cec5SDimitry Andric       DeleteConverter() : ContextualImplicitConverter(false, true) {}
36480b57cec5SDimitry Andric 
36490b57cec5SDimitry Andric       bool match(QualType ConvType) override {
36500b57cec5SDimitry Andric         // FIXME: If we have an operator T* and an operator void*, we must pick
36510b57cec5SDimitry Andric         // the operator T*.
36520b57cec5SDimitry Andric         if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
36530b57cec5SDimitry Andric           if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType())
36540b57cec5SDimitry Andric             return true;
36550b57cec5SDimitry Andric         return false;
36560b57cec5SDimitry Andric       }
36570b57cec5SDimitry Andric 
36580b57cec5SDimitry Andric       SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc,
36590b57cec5SDimitry Andric                                             QualType T) override {
36600b57cec5SDimitry Andric         return S.Diag(Loc, diag::err_delete_operand) << T;
36610b57cec5SDimitry Andric       }
36620b57cec5SDimitry Andric 
36630b57cec5SDimitry Andric       SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
36640b57cec5SDimitry Andric                                                QualType T) override {
36650b57cec5SDimitry Andric         return S.Diag(Loc, diag::err_delete_incomplete_class_type) << T;
36660b57cec5SDimitry Andric       }
36670b57cec5SDimitry Andric 
36680b57cec5SDimitry Andric       SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
36690b57cec5SDimitry Andric                                                  QualType T,
36700b57cec5SDimitry Andric                                                  QualType ConvTy) override {
36710b57cec5SDimitry Andric         return S.Diag(Loc, diag::err_delete_explicit_conversion) << T << ConvTy;
36720b57cec5SDimitry Andric       }
36730b57cec5SDimitry Andric 
36740b57cec5SDimitry Andric       SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
36750b57cec5SDimitry Andric                                              QualType ConvTy) override {
36760b57cec5SDimitry Andric         return S.Diag(Conv->getLocation(), diag::note_delete_conversion)
36770b57cec5SDimitry Andric           << ConvTy;
36780b57cec5SDimitry Andric       }
36790b57cec5SDimitry Andric 
36800b57cec5SDimitry Andric       SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
36810b57cec5SDimitry Andric                                               QualType T) override {
36820b57cec5SDimitry Andric         return S.Diag(Loc, diag::err_ambiguous_delete_operand) << T;
36830b57cec5SDimitry Andric       }
36840b57cec5SDimitry Andric 
36850b57cec5SDimitry Andric       SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
36860b57cec5SDimitry Andric                                           QualType ConvTy) override {
36870b57cec5SDimitry Andric         return S.Diag(Conv->getLocation(), diag::note_delete_conversion)
36880b57cec5SDimitry Andric           << ConvTy;
36890b57cec5SDimitry Andric       }
36900b57cec5SDimitry Andric 
36910b57cec5SDimitry Andric       SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc,
36920b57cec5SDimitry Andric                                                QualType T,
36930b57cec5SDimitry Andric                                                QualType ConvTy) override {
36940b57cec5SDimitry Andric         llvm_unreachable("conversion functions are permitted");
36950b57cec5SDimitry Andric       }
36960b57cec5SDimitry Andric     } Converter;
36970b57cec5SDimitry Andric 
36980b57cec5SDimitry Andric     Ex = PerformContextualImplicitConversion(StartLoc, Ex.get(), Converter);
36990b57cec5SDimitry Andric     if (Ex.isInvalid())
37000b57cec5SDimitry Andric       return ExprError();
37010b57cec5SDimitry Andric     Type = Ex.get()->getType();
37020b57cec5SDimitry Andric     if (!Converter.match(Type))
37030b57cec5SDimitry Andric       // FIXME: PerformContextualImplicitConversion should return ExprError
37040b57cec5SDimitry Andric       //        itself in this case.
37050b57cec5SDimitry Andric       return ExprError();
37060b57cec5SDimitry Andric 
3707a7dea167SDimitry Andric     QualType Pointee = Type->castAs<PointerType>()->getPointeeType();
37080b57cec5SDimitry Andric     QualType PointeeElem = Context.getBaseElementType(Pointee);
37090b57cec5SDimitry Andric 
37100b57cec5SDimitry Andric     if (Pointee.getAddressSpace() != LangAS::Default &&
37110b57cec5SDimitry Andric         !getLangOpts().OpenCLCPlusPlus)
37120b57cec5SDimitry Andric       return Diag(Ex.get()->getBeginLoc(),
37130b57cec5SDimitry Andric                   diag::err_address_space_qualified_delete)
37140b57cec5SDimitry Andric              << Pointee.getUnqualifiedType()
37150b57cec5SDimitry Andric              << Pointee.getQualifiers().getAddressSpaceAttributePrintValue();
37160b57cec5SDimitry Andric 
37170b57cec5SDimitry Andric     CXXRecordDecl *PointeeRD = nullptr;
37180b57cec5SDimitry Andric     if (Pointee->isVoidType() && !isSFINAEContext()) {
37190b57cec5SDimitry Andric       // The C++ standard bans deleting a pointer to a non-object type, which
37200b57cec5SDimitry Andric       // effectively bans deletion of "void*". However, most compilers support
37210b57cec5SDimitry Andric       // this, so we treat it as a warning unless we're in a SFINAE context.
37220b57cec5SDimitry Andric       Diag(StartLoc, diag::ext_delete_void_ptr_operand)
37230b57cec5SDimitry Andric         << Type << Ex.get()->getSourceRange();
37245ffd83dbSDimitry Andric     } else if (Pointee->isFunctionType() || Pointee->isVoidType() ||
37255ffd83dbSDimitry Andric                Pointee->isSizelessType()) {
37260b57cec5SDimitry Andric       return ExprError(Diag(StartLoc, diag::err_delete_operand)
37270b57cec5SDimitry Andric         << Type << Ex.get()->getSourceRange());
37280b57cec5SDimitry Andric     } else if (!Pointee->isDependentType()) {
37290b57cec5SDimitry Andric       // FIXME: This can result in errors if the definition was imported from a
37300b57cec5SDimitry Andric       // module but is hidden.
37310b57cec5SDimitry Andric       if (!RequireCompleteType(StartLoc, Pointee,
37320b57cec5SDimitry Andric                                diag::warn_delete_incomplete, Ex.get())) {
37330b57cec5SDimitry Andric         if (const RecordType *RT = PointeeElem->getAs<RecordType>())
37340b57cec5SDimitry Andric           PointeeRD = cast<CXXRecordDecl>(RT->getDecl());
37350b57cec5SDimitry Andric       }
37360b57cec5SDimitry Andric     }
37370b57cec5SDimitry Andric 
37380b57cec5SDimitry Andric     if (Pointee->isArrayType() && !ArrayForm) {
37390b57cec5SDimitry Andric       Diag(StartLoc, diag::warn_delete_array_type)
37400b57cec5SDimitry Andric           << Type << Ex.get()->getSourceRange()
37410b57cec5SDimitry Andric           << FixItHint::CreateInsertion(getLocForEndOfToken(StartLoc), "[]");
37420b57cec5SDimitry Andric       ArrayForm = true;
37430b57cec5SDimitry Andric     }
37440b57cec5SDimitry Andric 
37450b57cec5SDimitry Andric     DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
37460b57cec5SDimitry Andric                                       ArrayForm ? OO_Array_Delete : OO_Delete);
37470b57cec5SDimitry Andric 
37480b57cec5SDimitry Andric     if (PointeeRD) {
37490b57cec5SDimitry Andric       if (!UseGlobal &&
37500b57cec5SDimitry Andric           FindDeallocationFunction(StartLoc, PointeeRD, DeleteName,
37510b57cec5SDimitry Andric                                    OperatorDelete))
37520b57cec5SDimitry Andric         return ExprError();
37530b57cec5SDimitry Andric 
37540b57cec5SDimitry Andric       // If we're allocating an array of records, check whether the
37550b57cec5SDimitry Andric       // usual operator delete[] has a size_t parameter.
37560b57cec5SDimitry Andric       if (ArrayForm) {
37570b57cec5SDimitry Andric         // If the user specifically asked to use the global allocator,
37580b57cec5SDimitry Andric         // we'll need to do the lookup into the class.
37590b57cec5SDimitry Andric         if (UseGlobal)
37600b57cec5SDimitry Andric           UsualArrayDeleteWantsSize =
37610b57cec5SDimitry Andric             doesUsualArrayDeleteWantSize(*this, StartLoc, PointeeElem);
37620b57cec5SDimitry Andric 
37630b57cec5SDimitry Andric         // Otherwise, the usual operator delete[] should be the
37640b57cec5SDimitry Andric         // function we just found.
37650b57cec5SDimitry Andric         else if (OperatorDelete && isa<CXXMethodDecl>(OperatorDelete))
37660b57cec5SDimitry Andric           UsualArrayDeleteWantsSize =
37670b57cec5SDimitry Andric             UsualDeallocFnInfo(*this,
37680b57cec5SDimitry Andric                                DeclAccessPair::make(OperatorDelete, AS_public))
37690b57cec5SDimitry Andric               .HasSizeT;
37700b57cec5SDimitry Andric       }
37710b57cec5SDimitry Andric 
37720b57cec5SDimitry Andric       if (!PointeeRD->hasIrrelevantDestructor())
37730b57cec5SDimitry Andric         if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
37740b57cec5SDimitry Andric           MarkFunctionReferenced(StartLoc,
37750b57cec5SDimitry Andric                                     const_cast<CXXDestructorDecl*>(Dtor));
37760b57cec5SDimitry Andric           if (DiagnoseUseOfDecl(Dtor, StartLoc))
37770b57cec5SDimitry Andric             return ExprError();
37780b57cec5SDimitry Andric         }
37790b57cec5SDimitry Andric 
37800b57cec5SDimitry Andric       CheckVirtualDtorCall(PointeeRD->getDestructor(), StartLoc,
37810b57cec5SDimitry Andric                            /*IsDelete=*/true, /*CallCanBeVirtual=*/true,
37820b57cec5SDimitry Andric                            /*WarnOnNonAbstractTypes=*/!ArrayForm,
37830b57cec5SDimitry Andric                            SourceLocation());
37840b57cec5SDimitry Andric     }
37850b57cec5SDimitry Andric 
37860b57cec5SDimitry Andric     if (!OperatorDelete) {
37870b57cec5SDimitry Andric       if (getLangOpts().OpenCLCPlusPlus) {
37880b57cec5SDimitry Andric         Diag(StartLoc, diag::err_openclcxx_not_supported) << "default delete";
37890b57cec5SDimitry Andric         return ExprError();
37900b57cec5SDimitry Andric       }
37910b57cec5SDimitry Andric 
37920b57cec5SDimitry Andric       bool IsComplete = isCompleteType(StartLoc, Pointee);
37930b57cec5SDimitry Andric       bool CanProvideSize =
37940b57cec5SDimitry Andric           IsComplete && (!ArrayForm || UsualArrayDeleteWantsSize ||
37950b57cec5SDimitry Andric                          Pointee.isDestructedType());
37960b57cec5SDimitry Andric       bool Overaligned = hasNewExtendedAlignment(*this, Pointee);
37970b57cec5SDimitry Andric 
37980b57cec5SDimitry Andric       // Look for a global declaration.
37990b57cec5SDimitry Andric       OperatorDelete = FindUsualDeallocationFunction(StartLoc, CanProvideSize,
38000b57cec5SDimitry Andric                                                      Overaligned, DeleteName);
38010b57cec5SDimitry Andric     }
38020b57cec5SDimitry Andric 
38030b57cec5SDimitry Andric     MarkFunctionReferenced(StartLoc, OperatorDelete);
38040b57cec5SDimitry Andric 
38050b57cec5SDimitry Andric     // Check access and ambiguity of destructor if we're going to call it.
38060b57cec5SDimitry Andric     // Note that this is required even for a virtual delete.
38070b57cec5SDimitry Andric     bool IsVirtualDelete = false;
38080b57cec5SDimitry Andric     if (PointeeRD) {
38090b57cec5SDimitry Andric       if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
38100b57cec5SDimitry Andric         CheckDestructorAccess(Ex.get()->getExprLoc(), Dtor,
38110b57cec5SDimitry Andric                               PDiag(diag::err_access_dtor) << PointeeElem);
38120b57cec5SDimitry Andric         IsVirtualDelete = Dtor->isVirtual();
38130b57cec5SDimitry Andric       }
38140b57cec5SDimitry Andric     }
38150b57cec5SDimitry Andric 
38160b57cec5SDimitry Andric     DiagnoseUseOfDecl(OperatorDelete, StartLoc);
38170b57cec5SDimitry Andric 
38180b57cec5SDimitry Andric     // Convert the operand to the type of the first parameter of operator
38190b57cec5SDimitry Andric     // delete. This is only necessary if we selected a destroying operator
38200b57cec5SDimitry Andric     // delete that we are going to call (non-virtually); converting to void*
38210b57cec5SDimitry Andric     // is trivial and left to AST consumers to handle.
38220b57cec5SDimitry Andric     QualType ParamType = OperatorDelete->getParamDecl(0)->getType();
38230b57cec5SDimitry Andric     if (!IsVirtualDelete && !ParamType->getPointeeType()->isVoidType()) {
38240b57cec5SDimitry Andric       Qualifiers Qs = Pointee.getQualifiers();
38250b57cec5SDimitry Andric       if (Qs.hasCVRQualifiers()) {
38260b57cec5SDimitry Andric         // Qualifiers are irrelevant to this conversion; we're only looking
38270b57cec5SDimitry Andric         // for access and ambiguity.
38280b57cec5SDimitry Andric         Qs.removeCVRQualifiers();
38290b57cec5SDimitry Andric         QualType Unqual = Context.getPointerType(
38300b57cec5SDimitry Andric             Context.getQualifiedType(Pointee.getUnqualifiedType(), Qs));
38310b57cec5SDimitry Andric         Ex = ImpCastExprToType(Ex.get(), Unqual, CK_NoOp);
38320b57cec5SDimitry Andric       }
38330b57cec5SDimitry Andric       Ex = PerformImplicitConversion(Ex.get(), ParamType, AA_Passing);
38340b57cec5SDimitry Andric       if (Ex.isInvalid())
38350b57cec5SDimitry Andric         return ExprError();
38360b57cec5SDimitry Andric     }
38370b57cec5SDimitry Andric   }
38380b57cec5SDimitry Andric 
38390b57cec5SDimitry Andric   CXXDeleteExpr *Result = new (Context) CXXDeleteExpr(
38400b57cec5SDimitry Andric       Context.VoidTy, UseGlobal, ArrayForm, ArrayFormAsWritten,
38410b57cec5SDimitry Andric       UsualArrayDeleteWantsSize, OperatorDelete, Ex.get(), StartLoc);
38420b57cec5SDimitry Andric   AnalyzeDeleteExprMismatch(Result);
38430b57cec5SDimitry Andric   return Result;
38440b57cec5SDimitry Andric }
38450b57cec5SDimitry Andric 
resolveBuiltinNewDeleteOverload(Sema & S,CallExpr * TheCall,bool IsDelete,FunctionDecl * & Operator)38460b57cec5SDimitry Andric static bool resolveBuiltinNewDeleteOverload(Sema &S, CallExpr *TheCall,
38470b57cec5SDimitry Andric                                             bool IsDelete,
38480b57cec5SDimitry Andric                                             FunctionDecl *&Operator) {
38490b57cec5SDimitry Andric 
38500b57cec5SDimitry Andric   DeclarationName NewName = S.Context.DeclarationNames.getCXXOperatorName(
38510b57cec5SDimitry Andric       IsDelete ? OO_Delete : OO_New);
38520b57cec5SDimitry Andric 
38530b57cec5SDimitry Andric   LookupResult R(S, NewName, TheCall->getBeginLoc(), Sema::LookupOrdinaryName);
38540b57cec5SDimitry Andric   S.LookupQualifiedName(R, S.Context.getTranslationUnitDecl());
38550b57cec5SDimitry Andric   assert(!R.empty() && "implicitly declared allocation functions not found");
38560b57cec5SDimitry Andric   assert(!R.isAmbiguous() && "global allocation functions are ambiguous");
38570b57cec5SDimitry Andric 
38580b57cec5SDimitry Andric   // We do our own custom access checks below.
38590b57cec5SDimitry Andric   R.suppressDiagnostics();
38600b57cec5SDimitry Andric 
386181ad6265SDimitry Andric   SmallVector<Expr *, 8> Args(TheCall->arguments());
38620b57cec5SDimitry Andric   OverloadCandidateSet Candidates(R.getNameLoc(),
38630b57cec5SDimitry Andric                                   OverloadCandidateSet::CSK_Normal);
38640b57cec5SDimitry Andric   for (LookupResult::iterator FnOvl = R.begin(), FnOvlEnd = R.end();
38650b57cec5SDimitry Andric        FnOvl != FnOvlEnd; ++FnOvl) {
38660b57cec5SDimitry Andric     // Even member operator new/delete are implicitly treated as
38670b57cec5SDimitry Andric     // static, so don't use AddMemberCandidate.
38680b57cec5SDimitry Andric     NamedDecl *D = (*FnOvl)->getUnderlyingDecl();
38690b57cec5SDimitry Andric 
38700b57cec5SDimitry Andric     if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl>(D)) {
38710b57cec5SDimitry Andric       S.AddTemplateOverloadCandidate(FnTemplate, FnOvl.getPair(),
38720b57cec5SDimitry Andric                                      /*ExplicitTemplateArgs=*/nullptr, Args,
38730b57cec5SDimitry Andric                                      Candidates,
38740b57cec5SDimitry Andric                                      /*SuppressUserConversions=*/false);
38750b57cec5SDimitry Andric       continue;
38760b57cec5SDimitry Andric     }
38770b57cec5SDimitry Andric 
38780b57cec5SDimitry Andric     FunctionDecl *Fn = cast<FunctionDecl>(D);
38790b57cec5SDimitry Andric     S.AddOverloadCandidate(Fn, FnOvl.getPair(), Args, Candidates,
38800b57cec5SDimitry Andric                            /*SuppressUserConversions=*/false);
38810b57cec5SDimitry Andric   }
38820b57cec5SDimitry Andric 
38830b57cec5SDimitry Andric   SourceRange Range = TheCall->getSourceRange();
38840b57cec5SDimitry Andric 
38850b57cec5SDimitry Andric   // Do the resolution.
38860b57cec5SDimitry Andric   OverloadCandidateSet::iterator Best;
38870b57cec5SDimitry Andric   switch (Candidates.BestViableFunction(S, R.getNameLoc(), Best)) {
38880b57cec5SDimitry Andric   case OR_Success: {
38890b57cec5SDimitry Andric     // Got one!
38900b57cec5SDimitry Andric     FunctionDecl *FnDecl = Best->Function;
38910b57cec5SDimitry Andric     assert(R.getNamingClass() == nullptr &&
38920b57cec5SDimitry Andric            "class members should not be considered");
38930b57cec5SDimitry Andric 
38940b57cec5SDimitry Andric     if (!FnDecl->isReplaceableGlobalAllocationFunction()) {
38950b57cec5SDimitry Andric       S.Diag(R.getNameLoc(), diag::err_builtin_operator_new_delete_not_usual)
38960b57cec5SDimitry Andric           << (IsDelete ? 1 : 0) << Range;
38970b57cec5SDimitry Andric       S.Diag(FnDecl->getLocation(), diag::note_non_usual_function_declared_here)
38980b57cec5SDimitry Andric           << R.getLookupName() << FnDecl->getSourceRange();
38990b57cec5SDimitry Andric       return true;
39000b57cec5SDimitry Andric     }
39010b57cec5SDimitry Andric 
39020b57cec5SDimitry Andric     Operator = FnDecl;
39030b57cec5SDimitry Andric     return false;
39040b57cec5SDimitry Andric   }
39050b57cec5SDimitry Andric 
39060b57cec5SDimitry Andric   case OR_No_Viable_Function:
39070b57cec5SDimitry Andric     Candidates.NoteCandidates(
39080b57cec5SDimitry Andric         PartialDiagnosticAt(R.getNameLoc(),
39090b57cec5SDimitry Andric                             S.PDiag(diag::err_ovl_no_viable_function_in_call)
39100b57cec5SDimitry Andric                                 << R.getLookupName() << Range),
39110b57cec5SDimitry Andric         S, OCD_AllCandidates, Args);
39120b57cec5SDimitry Andric     return true;
39130b57cec5SDimitry Andric 
39140b57cec5SDimitry Andric   case OR_Ambiguous:
39150b57cec5SDimitry Andric     Candidates.NoteCandidates(
39160b57cec5SDimitry Andric         PartialDiagnosticAt(R.getNameLoc(),
39170b57cec5SDimitry Andric                             S.PDiag(diag::err_ovl_ambiguous_call)
39180b57cec5SDimitry Andric                                 << R.getLookupName() << Range),
3919480093f4SDimitry Andric         S, OCD_AmbiguousCandidates, Args);
39200b57cec5SDimitry Andric     return true;
39210b57cec5SDimitry Andric 
39220b57cec5SDimitry Andric   case OR_Deleted: {
39230b57cec5SDimitry Andric     Candidates.NoteCandidates(
39240b57cec5SDimitry Andric         PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_deleted_call)
39250b57cec5SDimitry Andric                                                 << R.getLookupName() << Range),
39260b57cec5SDimitry Andric         S, OCD_AllCandidates, Args);
39270b57cec5SDimitry Andric     return true;
39280b57cec5SDimitry Andric   }
39290b57cec5SDimitry Andric   }
39300b57cec5SDimitry Andric   llvm_unreachable("Unreachable, bad result from BestViableFunction");
39310b57cec5SDimitry Andric }
39320b57cec5SDimitry Andric 
39330b57cec5SDimitry Andric ExprResult
SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult,bool IsDelete)39340b57cec5SDimitry Andric Sema::SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult,
39350b57cec5SDimitry Andric                                              bool IsDelete) {
39360b57cec5SDimitry Andric   CallExpr *TheCall = cast<CallExpr>(TheCallResult.get());
39370b57cec5SDimitry Andric   if (!getLangOpts().CPlusPlus) {
39380b57cec5SDimitry Andric     Diag(TheCall->getExprLoc(), diag::err_builtin_requires_language)
39390b57cec5SDimitry Andric         << (IsDelete ? "__builtin_operator_delete" : "__builtin_operator_new")
39400b57cec5SDimitry Andric         << "C++";
39410b57cec5SDimitry Andric     return ExprError();
39420b57cec5SDimitry Andric   }
39430b57cec5SDimitry Andric   // CodeGen assumes it can find the global new and delete to call,
39440b57cec5SDimitry Andric   // so ensure that they are declared.
39450b57cec5SDimitry Andric   DeclareGlobalNewDelete();
39460b57cec5SDimitry Andric 
39470b57cec5SDimitry Andric   FunctionDecl *OperatorNewOrDelete = nullptr;
39480b57cec5SDimitry Andric   if (resolveBuiltinNewDeleteOverload(*this, TheCall, IsDelete,
39490b57cec5SDimitry Andric                                       OperatorNewOrDelete))
39500b57cec5SDimitry Andric     return ExprError();
39510b57cec5SDimitry Andric   assert(OperatorNewOrDelete && "should be found");
39520b57cec5SDimitry Andric 
39530b57cec5SDimitry Andric   DiagnoseUseOfDecl(OperatorNewOrDelete, TheCall->getExprLoc());
39540b57cec5SDimitry Andric   MarkFunctionReferenced(TheCall->getExprLoc(), OperatorNewOrDelete);
39550b57cec5SDimitry Andric 
39560b57cec5SDimitry Andric   TheCall->setType(OperatorNewOrDelete->getReturnType());
39570b57cec5SDimitry Andric   for (unsigned i = 0; i != TheCall->getNumArgs(); ++i) {
39580b57cec5SDimitry Andric     QualType ParamTy = OperatorNewOrDelete->getParamDecl(i)->getType();
39590b57cec5SDimitry Andric     InitializedEntity Entity =
39600b57cec5SDimitry Andric         InitializedEntity::InitializeParameter(Context, ParamTy, false);
39610b57cec5SDimitry Andric     ExprResult Arg = PerformCopyInitialization(
39620b57cec5SDimitry Andric         Entity, TheCall->getArg(i)->getBeginLoc(), TheCall->getArg(i));
39630b57cec5SDimitry Andric     if (Arg.isInvalid())
39640b57cec5SDimitry Andric       return ExprError();
39650b57cec5SDimitry Andric     TheCall->setArg(i, Arg.get());
39660b57cec5SDimitry Andric   }
39670b57cec5SDimitry Andric   auto Callee = dyn_cast<ImplicitCastExpr>(TheCall->getCallee());
39680b57cec5SDimitry Andric   assert(Callee && Callee->getCastKind() == CK_BuiltinFnToFnPtr &&
39690b57cec5SDimitry Andric          "Callee expected to be implicit cast to a builtin function pointer");
39700b57cec5SDimitry Andric   Callee->setType(OperatorNewOrDelete->getType());
39710b57cec5SDimitry Andric 
39720b57cec5SDimitry Andric   return TheCallResult;
39730b57cec5SDimitry Andric }
39740b57cec5SDimitry Andric 
CheckVirtualDtorCall(CXXDestructorDecl * dtor,SourceLocation Loc,bool IsDelete,bool CallCanBeVirtual,bool WarnOnNonAbstractTypes,SourceLocation DtorLoc)39750b57cec5SDimitry Andric void Sema::CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc,
39760b57cec5SDimitry Andric                                 bool IsDelete, bool CallCanBeVirtual,
39770b57cec5SDimitry Andric                                 bool WarnOnNonAbstractTypes,
39780b57cec5SDimitry Andric                                 SourceLocation DtorLoc) {
39790b57cec5SDimitry Andric   if (!dtor || dtor->isVirtual() || !CallCanBeVirtual || isUnevaluatedContext())
39800b57cec5SDimitry Andric     return;
39810b57cec5SDimitry Andric 
39820b57cec5SDimitry Andric   // C++ [expr.delete]p3:
39830b57cec5SDimitry Andric   //   In the first alternative (delete object), if the static type of the
39840b57cec5SDimitry Andric   //   object to be deleted is different from its dynamic type, the static
39850b57cec5SDimitry Andric   //   type shall be a base class of the dynamic type of the object to be
39860b57cec5SDimitry Andric   //   deleted and the static type shall have a virtual destructor or the
39870b57cec5SDimitry Andric   //   behavior is undefined.
39880b57cec5SDimitry Andric   //
39890b57cec5SDimitry Andric   const CXXRecordDecl *PointeeRD = dtor->getParent();
39900b57cec5SDimitry Andric   // Note: a final class cannot be derived from, no issue there
39910b57cec5SDimitry Andric   if (!PointeeRD->isPolymorphic() || PointeeRD->hasAttr<FinalAttr>())
39920b57cec5SDimitry Andric     return;
39930b57cec5SDimitry Andric 
39940b57cec5SDimitry Andric   // If the superclass is in a system header, there's nothing that can be done.
39950b57cec5SDimitry Andric   // The `delete` (where we emit the warning) can be in a system header,
39960b57cec5SDimitry Andric   // what matters for this warning is where the deleted type is defined.
39970b57cec5SDimitry Andric   if (getSourceManager().isInSystemHeader(PointeeRD->getLocation()))
39980b57cec5SDimitry Andric     return;
39990b57cec5SDimitry Andric 
40005f757f3fSDimitry Andric   QualType ClassType = dtor->getFunctionObjectParameterType();
40010b57cec5SDimitry Andric   if (PointeeRD->isAbstract()) {
40020b57cec5SDimitry Andric     // If the class is abstract, we warn by default, because we're
40030b57cec5SDimitry Andric     // sure the code has undefined behavior.
40040b57cec5SDimitry Andric     Diag(Loc, diag::warn_delete_abstract_non_virtual_dtor) << (IsDelete ? 0 : 1)
40050b57cec5SDimitry Andric                                                            << ClassType;
40060b57cec5SDimitry Andric   } else if (WarnOnNonAbstractTypes) {
40070b57cec5SDimitry Andric     // Otherwise, if this is not an array delete, it's a bit suspect,
40080b57cec5SDimitry Andric     // but not necessarily wrong.
40090b57cec5SDimitry Andric     Diag(Loc, diag::warn_delete_non_virtual_dtor) << (IsDelete ? 0 : 1)
40100b57cec5SDimitry Andric                                                   << ClassType;
40110b57cec5SDimitry Andric   }
40120b57cec5SDimitry Andric   if (!IsDelete) {
40130b57cec5SDimitry Andric     std::string TypeStr;
40140b57cec5SDimitry Andric     ClassType.getAsStringInternal(TypeStr, getPrintingPolicy());
40150b57cec5SDimitry Andric     Diag(DtorLoc, diag::note_delete_non_virtual)
40160b57cec5SDimitry Andric         << FixItHint::CreateInsertion(DtorLoc, TypeStr + "::");
40170b57cec5SDimitry Andric   }
40180b57cec5SDimitry Andric }
40190b57cec5SDimitry Andric 
ActOnConditionVariable(Decl * ConditionVar,SourceLocation StmtLoc,ConditionKind CK)40200b57cec5SDimitry Andric Sema::ConditionResult Sema::ActOnConditionVariable(Decl *ConditionVar,
40210b57cec5SDimitry Andric                                                    SourceLocation StmtLoc,
40220b57cec5SDimitry Andric                                                    ConditionKind CK) {
40230b57cec5SDimitry Andric   ExprResult E =
40240b57cec5SDimitry Andric       CheckConditionVariable(cast<VarDecl>(ConditionVar), StmtLoc, CK);
40250b57cec5SDimitry Andric   if (E.isInvalid())
40260b57cec5SDimitry Andric     return ConditionError();
40270b57cec5SDimitry Andric   return ConditionResult(*this, ConditionVar, MakeFullExpr(E.get(), StmtLoc),
40280b57cec5SDimitry Andric                          CK == ConditionKind::ConstexprIf);
40290b57cec5SDimitry Andric }
40300b57cec5SDimitry Andric 
40310b57cec5SDimitry Andric /// Check the use of the given variable as a C++ condition in an if,
40320b57cec5SDimitry Andric /// while, do-while, or switch statement.
CheckConditionVariable(VarDecl * ConditionVar,SourceLocation StmtLoc,ConditionKind CK)40330b57cec5SDimitry Andric ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
40340b57cec5SDimitry Andric                                         SourceLocation StmtLoc,
40350b57cec5SDimitry Andric                                         ConditionKind CK) {
40360b57cec5SDimitry Andric   if (ConditionVar->isInvalidDecl())
40370b57cec5SDimitry Andric     return ExprError();
40380b57cec5SDimitry Andric 
40390b57cec5SDimitry Andric   QualType T = ConditionVar->getType();
40400b57cec5SDimitry Andric 
40410b57cec5SDimitry Andric   // C++ [stmt.select]p2:
40420b57cec5SDimitry Andric   //   The declarator shall not specify a function or an array.
40430b57cec5SDimitry Andric   if (T->isFunctionType())
40440b57cec5SDimitry Andric     return ExprError(Diag(ConditionVar->getLocation(),
40450b57cec5SDimitry Andric                           diag::err_invalid_use_of_function_type)
40460b57cec5SDimitry Andric                        << ConditionVar->getSourceRange());
40470b57cec5SDimitry Andric   else if (T->isArrayType())
40480b57cec5SDimitry Andric     return ExprError(Diag(ConditionVar->getLocation(),
40490b57cec5SDimitry Andric                           diag::err_invalid_use_of_array_type)
40500b57cec5SDimitry Andric                      << ConditionVar->getSourceRange());
40510b57cec5SDimitry Andric 
40520b57cec5SDimitry Andric   ExprResult Condition = BuildDeclRefExpr(
40530b57cec5SDimitry Andric       ConditionVar, ConditionVar->getType().getNonReferenceType(), VK_LValue,
40540b57cec5SDimitry Andric       ConditionVar->getLocation());
40550b57cec5SDimitry Andric 
40560b57cec5SDimitry Andric   switch (CK) {
40570b57cec5SDimitry Andric   case ConditionKind::Boolean:
40580b57cec5SDimitry Andric     return CheckBooleanCondition(StmtLoc, Condition.get());
40590b57cec5SDimitry Andric 
40600b57cec5SDimitry Andric   case ConditionKind::ConstexprIf:
40610b57cec5SDimitry Andric     return CheckBooleanCondition(StmtLoc, Condition.get(), true);
40620b57cec5SDimitry Andric 
40630b57cec5SDimitry Andric   case ConditionKind::Switch:
40640b57cec5SDimitry Andric     return CheckSwitchCondition(StmtLoc, Condition.get());
40650b57cec5SDimitry Andric   }
40660b57cec5SDimitry Andric 
40670b57cec5SDimitry Andric   llvm_unreachable("unexpected condition kind");
40680b57cec5SDimitry Andric }
40690b57cec5SDimitry Andric 
40700b57cec5SDimitry Andric /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.
CheckCXXBooleanCondition(Expr * CondExpr,bool IsConstexpr)40710b57cec5SDimitry Andric ExprResult Sema::CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr) {
4072fe6060f1SDimitry Andric   // C++11 6.4p4:
40730b57cec5SDimitry Andric   // The value of a condition that is an initialized declaration in a statement
40740b57cec5SDimitry Andric   // other than a switch statement is the value of the declared variable
40750b57cec5SDimitry Andric   // implicitly converted to type bool. If that conversion is ill-formed, the
40760b57cec5SDimitry Andric   // program is ill-formed.
40770b57cec5SDimitry Andric   // The value of a condition that is an expression is the value of the
40780b57cec5SDimitry Andric   // expression, implicitly converted to bool.
40790b57cec5SDimitry Andric   //
408006c3fb27SDimitry Andric   // C++23 8.5.2p2
4081fe6060f1SDimitry Andric   // If the if statement is of the form if constexpr, the value of the condition
4082fe6060f1SDimitry Andric   // is contextually converted to bool and the converted expression shall be
4083fe6060f1SDimitry Andric   // a constant expression.
4084fe6060f1SDimitry Andric   //
4085fe6060f1SDimitry Andric 
4086fe6060f1SDimitry Andric   ExprResult E = PerformContextuallyConvertToBool(CondExpr);
4087fe6060f1SDimitry Andric   if (!IsConstexpr || E.isInvalid() || E.get()->isValueDependent())
4088fe6060f1SDimitry Andric     return E;
4089fe6060f1SDimitry Andric 
40900b57cec5SDimitry Andric   // FIXME: Return this value to the caller so they don't need to recompute it.
4091fe6060f1SDimitry Andric   llvm::APSInt Cond;
4092fe6060f1SDimitry Andric   E = VerifyIntegerConstantExpression(
4093fe6060f1SDimitry Andric       E.get(), &Cond,
4094fe6060f1SDimitry Andric       diag::err_constexpr_if_condition_expression_is_not_constant);
4095fe6060f1SDimitry Andric   return E;
40960b57cec5SDimitry Andric }
40970b57cec5SDimitry Andric 
40980b57cec5SDimitry Andric /// Helper function to determine whether this is the (deprecated) C++
40990b57cec5SDimitry Andric /// conversion from a string literal to a pointer to non-const char or
41000b57cec5SDimitry Andric /// non-const wchar_t (for narrow and wide string literals,
41010b57cec5SDimitry Andric /// respectively).
41020b57cec5SDimitry Andric bool
IsStringLiteralToNonConstPointerConversion(Expr * From,QualType ToType)41030b57cec5SDimitry Andric Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {
41040b57cec5SDimitry Andric   // Look inside the implicit cast, if it exists.
41050b57cec5SDimitry Andric   if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(From))
41060b57cec5SDimitry Andric     From = Cast->getSubExpr();
41070b57cec5SDimitry Andric 
41080b57cec5SDimitry Andric   // A string literal (2.13.4) that is not a wide string literal can
41090b57cec5SDimitry Andric   // be converted to an rvalue of type "pointer to char"; a wide
41100b57cec5SDimitry Andric   // string literal can be converted to an rvalue of type "pointer
41110b57cec5SDimitry Andric   // to wchar_t" (C++ 4.2p2).
41120b57cec5SDimitry Andric   if (StringLiteral *StrLit = dyn_cast<StringLiteral>(From->IgnoreParens()))
41130b57cec5SDimitry Andric     if (const PointerType *ToPtrType = ToType->getAs<PointerType>())
41140b57cec5SDimitry Andric       if (const BuiltinType *ToPointeeType
41150b57cec5SDimitry Andric           = ToPtrType->getPointeeType()->getAs<BuiltinType>()) {
41160b57cec5SDimitry Andric         // This conversion is considered only when there is an
41170b57cec5SDimitry Andric         // explicit appropriate pointer target type (C++ 4.2p2).
41180b57cec5SDimitry Andric         if (!ToPtrType->getPointeeType().hasQualifiers()) {
41190b57cec5SDimitry Andric           switch (StrLit->getKind()) {
41205f757f3fSDimitry Andric           case StringLiteralKind::UTF8:
41215f757f3fSDimitry Andric           case StringLiteralKind::UTF16:
41225f757f3fSDimitry Andric           case StringLiteralKind::UTF32:
41230b57cec5SDimitry Andric             // We don't allow UTF literals to be implicitly converted
41240b57cec5SDimitry Andric             break;
41255f757f3fSDimitry Andric           case StringLiteralKind::Ordinary:
41260b57cec5SDimitry Andric             return (ToPointeeType->getKind() == BuiltinType::Char_U ||
41270b57cec5SDimitry Andric                     ToPointeeType->getKind() == BuiltinType::Char_S);
41285f757f3fSDimitry Andric           case StringLiteralKind::Wide:
41290b57cec5SDimitry Andric             return Context.typesAreCompatible(Context.getWideCharType(),
41300b57cec5SDimitry Andric                                               QualType(ToPointeeType, 0));
41315f757f3fSDimitry Andric           case StringLiteralKind::Unevaluated:
413206c3fb27SDimitry Andric             assert(false && "Unevaluated string literal in expression");
413306c3fb27SDimitry Andric             break;
41340b57cec5SDimitry Andric           }
41350b57cec5SDimitry Andric         }
41360b57cec5SDimitry Andric       }
41370b57cec5SDimitry Andric 
41380b57cec5SDimitry Andric   return false;
41390b57cec5SDimitry Andric }
41400b57cec5SDimitry Andric 
BuildCXXCastArgument(Sema & S,SourceLocation CastLoc,QualType Ty,CastKind Kind,CXXMethodDecl * Method,DeclAccessPair FoundDecl,bool HadMultipleCandidates,Expr * From)41410b57cec5SDimitry Andric static ExprResult BuildCXXCastArgument(Sema &S,
41420b57cec5SDimitry Andric                                        SourceLocation CastLoc,
41430b57cec5SDimitry Andric                                        QualType Ty,
41440b57cec5SDimitry Andric                                        CastKind Kind,
41450b57cec5SDimitry Andric                                        CXXMethodDecl *Method,
41460b57cec5SDimitry Andric                                        DeclAccessPair FoundDecl,
41470b57cec5SDimitry Andric                                        bool HadMultipleCandidates,
41480b57cec5SDimitry Andric                                        Expr *From) {
41490b57cec5SDimitry Andric   switch (Kind) {
41500b57cec5SDimitry Andric   default: llvm_unreachable("Unhandled cast kind!");
41510b57cec5SDimitry Andric   case CK_ConstructorConversion: {
41520b57cec5SDimitry Andric     CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Method);
41530b57cec5SDimitry Andric     SmallVector<Expr*, 8> ConstructorArgs;
41540b57cec5SDimitry Andric 
41550b57cec5SDimitry Andric     if (S.RequireNonAbstractType(CastLoc, Ty,
41560b57cec5SDimitry Andric                                  diag::err_allocation_of_abstract_type))
41570b57cec5SDimitry Andric       return ExprError();
41580b57cec5SDimitry Andric 
4159fe6060f1SDimitry Andric     if (S.CompleteConstructorCall(Constructor, Ty, From, CastLoc,
4160fe6060f1SDimitry Andric                                   ConstructorArgs))
41610b57cec5SDimitry Andric       return ExprError();
41620b57cec5SDimitry Andric 
41630b57cec5SDimitry Andric     S.CheckConstructorAccess(CastLoc, Constructor, FoundDecl,
41640b57cec5SDimitry Andric                              InitializedEntity::InitializeTemporary(Ty));
41650b57cec5SDimitry Andric     if (S.DiagnoseUseOfDecl(Method, CastLoc))
41660b57cec5SDimitry Andric       return ExprError();
41670b57cec5SDimitry Andric 
41680b57cec5SDimitry Andric     ExprResult Result = S.BuildCXXConstructExpr(
41690b57cec5SDimitry Andric         CastLoc, Ty, FoundDecl, cast<CXXConstructorDecl>(Method),
41700b57cec5SDimitry Andric         ConstructorArgs, HadMultipleCandidates,
41710b57cec5SDimitry Andric         /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
41725f757f3fSDimitry Andric         CXXConstructionKind::Complete, SourceRange());
41730b57cec5SDimitry Andric     if (Result.isInvalid())
41740b57cec5SDimitry Andric       return ExprError();
41750b57cec5SDimitry Andric 
41760b57cec5SDimitry Andric     return S.MaybeBindToTemporary(Result.getAs<Expr>());
41770b57cec5SDimitry Andric   }
41780b57cec5SDimitry Andric 
41790b57cec5SDimitry Andric   case CK_UserDefinedConversion: {
41800b57cec5SDimitry Andric     assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
41810b57cec5SDimitry Andric 
41820b57cec5SDimitry Andric     S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl);
41830b57cec5SDimitry Andric     if (S.DiagnoseUseOfDecl(Method, CastLoc))
41840b57cec5SDimitry Andric       return ExprError();
41850b57cec5SDimitry Andric 
41860b57cec5SDimitry Andric     // Create an implicit call expr that calls it.
41870b57cec5SDimitry Andric     CXXConversionDecl *Conv = cast<CXXConversionDecl>(Method);
41880b57cec5SDimitry Andric     ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Conv,
41890b57cec5SDimitry Andric                                                  HadMultipleCandidates);
41900b57cec5SDimitry Andric     if (Result.isInvalid())
41910b57cec5SDimitry Andric       return ExprError();
41920b57cec5SDimitry Andric     // Record usage of conversion in an implicit cast.
41930b57cec5SDimitry Andric     Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(),
41940b57cec5SDimitry Andric                                       CK_UserDefinedConversion, Result.get(),
4195e8d8bef9SDimitry Andric                                       nullptr, Result.get()->getValueKind(),
4196e8d8bef9SDimitry Andric                                       S.CurFPFeatureOverrides());
41970b57cec5SDimitry Andric 
41980b57cec5SDimitry Andric     return S.MaybeBindToTemporary(Result.get());
41990b57cec5SDimitry Andric   }
42000b57cec5SDimitry Andric   }
42010b57cec5SDimitry Andric }
42020b57cec5SDimitry Andric 
42030b57cec5SDimitry Andric /// PerformImplicitConversion - Perform an implicit conversion of the
42040b57cec5SDimitry Andric /// expression From to the type ToType using the pre-computed implicit
42050b57cec5SDimitry Andric /// conversion sequence ICS. Returns the converted
42060b57cec5SDimitry Andric /// expression. Action is the kind of conversion we're performing,
42070b57cec5SDimitry Andric /// used in the error message.
42080b57cec5SDimitry Andric ExprResult
PerformImplicitConversion(Expr * From,QualType ToType,const ImplicitConversionSequence & ICS,AssignmentAction Action,CheckedConversionKind CCK)42090b57cec5SDimitry Andric Sema::PerformImplicitConversion(Expr *From, QualType ToType,
42100b57cec5SDimitry Andric                                 const ImplicitConversionSequence &ICS,
42110b57cec5SDimitry Andric                                 AssignmentAction Action,
42120b57cec5SDimitry Andric                                 CheckedConversionKind CCK) {
42130b57cec5SDimitry Andric   // C++ [over.match.oper]p7: [...] operands of class type are converted [...]
42140b57cec5SDimitry Andric   if (CCK == CCK_ForBuiltinOverloadedOp && !From->getType()->isRecordType())
42150b57cec5SDimitry Andric     return From;
42160b57cec5SDimitry Andric 
42170b57cec5SDimitry Andric   switch (ICS.getKind()) {
42180b57cec5SDimitry Andric   case ImplicitConversionSequence::StandardConversion: {
42190b57cec5SDimitry Andric     ExprResult Res = PerformImplicitConversion(From, ToType, ICS.Standard,
42200b57cec5SDimitry Andric                                                Action, CCK);
42210b57cec5SDimitry Andric     if (Res.isInvalid())
42220b57cec5SDimitry Andric       return ExprError();
42230b57cec5SDimitry Andric     From = Res.get();
42240b57cec5SDimitry Andric     break;
42250b57cec5SDimitry Andric   }
42260b57cec5SDimitry Andric 
42270b57cec5SDimitry Andric   case ImplicitConversionSequence::UserDefinedConversion: {
42280b57cec5SDimitry Andric 
42290b57cec5SDimitry Andric       FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
42300b57cec5SDimitry Andric       CastKind CastKind;
42310b57cec5SDimitry Andric       QualType BeforeToType;
42320b57cec5SDimitry Andric       assert(FD && "no conversion function for user-defined conversion seq");
42330b57cec5SDimitry Andric       if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) {
42340b57cec5SDimitry Andric         CastKind = CK_UserDefinedConversion;
42350b57cec5SDimitry Andric 
42360b57cec5SDimitry Andric         // If the user-defined conversion is specified by a conversion function,
42370b57cec5SDimitry Andric         // the initial standard conversion sequence converts the source type to
42380b57cec5SDimitry Andric         // the implicit object parameter of the conversion function.
42390b57cec5SDimitry Andric         BeforeToType = Context.getTagDeclType(Conv->getParent());
42400b57cec5SDimitry Andric       } else {
42410b57cec5SDimitry Andric         const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(FD);
42420b57cec5SDimitry Andric         CastKind = CK_ConstructorConversion;
42430b57cec5SDimitry Andric         // Do no conversion if dealing with ... for the first conversion.
42440b57cec5SDimitry Andric         if (!ICS.UserDefined.EllipsisConversion) {
42450b57cec5SDimitry Andric           // If the user-defined conversion is specified by a constructor, the
42460b57cec5SDimitry Andric           // initial standard conversion sequence converts the source type to
42470b57cec5SDimitry Andric           // the type required by the argument of the constructor
42480b57cec5SDimitry Andric           BeforeToType = Ctor->getParamDecl(0)->getType().getNonReferenceType();
42490b57cec5SDimitry Andric         }
42500b57cec5SDimitry Andric       }
42510b57cec5SDimitry Andric       // Watch out for ellipsis conversion.
42520b57cec5SDimitry Andric       if (!ICS.UserDefined.EllipsisConversion) {
42530b57cec5SDimitry Andric         ExprResult Res =
42540b57cec5SDimitry Andric           PerformImplicitConversion(From, BeforeToType,
42550b57cec5SDimitry Andric                                     ICS.UserDefined.Before, AA_Converting,
42560b57cec5SDimitry Andric                                     CCK);
42570b57cec5SDimitry Andric         if (Res.isInvalid())
42580b57cec5SDimitry Andric           return ExprError();
42590b57cec5SDimitry Andric         From = Res.get();
42600b57cec5SDimitry Andric       }
42610b57cec5SDimitry Andric 
42620b57cec5SDimitry Andric       ExprResult CastArg = BuildCXXCastArgument(
42630b57cec5SDimitry Andric           *this, From->getBeginLoc(), ToType.getNonReferenceType(), CastKind,
42640b57cec5SDimitry Andric           cast<CXXMethodDecl>(FD), ICS.UserDefined.FoundConversionFunction,
42650b57cec5SDimitry Andric           ICS.UserDefined.HadMultipleCandidates, From);
42660b57cec5SDimitry Andric 
42670b57cec5SDimitry Andric       if (CastArg.isInvalid())
42680b57cec5SDimitry Andric         return ExprError();
42690b57cec5SDimitry Andric 
42700b57cec5SDimitry Andric       From = CastArg.get();
42710b57cec5SDimitry Andric 
42720b57cec5SDimitry Andric       // C++ [over.match.oper]p7:
42730b57cec5SDimitry Andric       //   [...] the second standard conversion sequence of a user-defined
42740b57cec5SDimitry Andric       //   conversion sequence is not applied.
42750b57cec5SDimitry Andric       if (CCK == CCK_ForBuiltinOverloadedOp)
42760b57cec5SDimitry Andric         return From;
42770b57cec5SDimitry Andric 
42780b57cec5SDimitry Andric       return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
42790b57cec5SDimitry Andric                                        AA_Converting, CCK);
42800b57cec5SDimitry Andric   }
42810b57cec5SDimitry Andric 
42820b57cec5SDimitry Andric   case ImplicitConversionSequence::AmbiguousConversion:
42830b57cec5SDimitry Andric     ICS.DiagnoseAmbiguousConversion(*this, From->getExprLoc(),
42840b57cec5SDimitry Andric                           PDiag(diag::err_typecheck_ambiguous_condition)
42850b57cec5SDimitry Andric                             << From->getSourceRange());
42860b57cec5SDimitry Andric     return ExprError();
42870b57cec5SDimitry Andric 
42880b57cec5SDimitry Andric   case ImplicitConversionSequence::EllipsisConversion:
4289bdd1243dSDimitry Andric   case ImplicitConversionSequence::StaticObjectArgumentConversion:
4290bdd1243dSDimitry Andric     llvm_unreachable("bad conversion");
42910b57cec5SDimitry Andric 
42920b57cec5SDimitry Andric   case ImplicitConversionSequence::BadConversion:
42935ffd83dbSDimitry Andric     Sema::AssignConvertType ConvTy =
42945ffd83dbSDimitry Andric         CheckAssignmentConstraints(From->getExprLoc(), ToType, From->getType());
42955ffd83dbSDimitry Andric     bool Diagnosed = DiagnoseAssignmentResult(
42965ffd83dbSDimitry Andric         ConvTy == Compatible ? Incompatible : ConvTy, From->getExprLoc(),
42975ffd83dbSDimitry Andric         ToType, From->getType(), From, Action);
42980b57cec5SDimitry Andric     assert(Diagnosed && "failed to diagnose bad conversion"); (void)Diagnosed;
42990b57cec5SDimitry Andric     return ExprError();
43000b57cec5SDimitry Andric   }
43010b57cec5SDimitry Andric 
43020b57cec5SDimitry Andric   // Everything went well.
43030b57cec5SDimitry Andric   return From;
43040b57cec5SDimitry Andric }
43050b57cec5SDimitry Andric 
43060b57cec5SDimitry Andric /// PerformImplicitConversion - Perform an implicit conversion of the
43070b57cec5SDimitry Andric /// expression From to the type ToType by following the standard
43080b57cec5SDimitry Andric /// conversion sequence SCS. Returns the converted
43090b57cec5SDimitry Andric /// expression. Flavor is the context in which we're performing this
43100b57cec5SDimitry Andric /// conversion, for use in error messages.
43110b57cec5SDimitry Andric ExprResult
PerformImplicitConversion(Expr * From,QualType ToType,const StandardConversionSequence & SCS,AssignmentAction Action,CheckedConversionKind CCK)43120b57cec5SDimitry Andric Sema::PerformImplicitConversion(Expr *From, QualType ToType,
43130b57cec5SDimitry Andric                                 const StandardConversionSequence& SCS,
43140b57cec5SDimitry Andric                                 AssignmentAction Action,
43150b57cec5SDimitry Andric                                 CheckedConversionKind CCK) {
43160b57cec5SDimitry Andric   bool CStyle = (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast);
43170b57cec5SDimitry Andric 
43180b57cec5SDimitry Andric   // Overall FIXME: we are recomputing too many types here and doing far too
43190b57cec5SDimitry Andric   // much extra work. What this means is that we need to keep track of more
43200b57cec5SDimitry Andric   // information that is computed when we try the implicit conversion initially,
43210b57cec5SDimitry Andric   // so that we don't need to recompute anything here.
43220b57cec5SDimitry Andric   QualType FromType = From->getType();
43230b57cec5SDimitry Andric 
43240b57cec5SDimitry Andric   if (SCS.CopyConstructor) {
43250b57cec5SDimitry Andric     // FIXME: When can ToType be a reference type?
43260b57cec5SDimitry Andric     assert(!ToType->isReferenceType());
43270b57cec5SDimitry Andric     if (SCS.Second == ICK_Derived_To_Base) {
43280b57cec5SDimitry Andric       SmallVector<Expr*, 8> ConstructorArgs;
4329fe6060f1SDimitry Andric       if (CompleteConstructorCall(
4330fe6060f1SDimitry Andric               cast<CXXConstructorDecl>(SCS.CopyConstructor), ToType, From,
4331fe6060f1SDimitry Andric               /*FIXME:ConstructLoc*/ SourceLocation(), ConstructorArgs))
43320b57cec5SDimitry Andric         return ExprError();
43330b57cec5SDimitry Andric       return BuildCXXConstructExpr(
43340b57cec5SDimitry Andric           /*FIXME:ConstructLoc*/ SourceLocation(), ToType,
43355f757f3fSDimitry Andric           SCS.FoundCopyConstructor, SCS.CopyConstructor, ConstructorArgs,
43365f757f3fSDimitry Andric           /*HadMultipleCandidates*/ false,
43370b57cec5SDimitry Andric           /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
43385f757f3fSDimitry Andric           CXXConstructionKind::Complete, SourceRange());
43390b57cec5SDimitry Andric     }
43400b57cec5SDimitry Andric     return BuildCXXConstructExpr(
43410b57cec5SDimitry Andric         /*FIXME:ConstructLoc*/ SourceLocation(), ToType,
43425f757f3fSDimitry Andric         SCS.FoundCopyConstructor, SCS.CopyConstructor, From,
43435f757f3fSDimitry Andric         /*HadMultipleCandidates*/ false,
43440b57cec5SDimitry Andric         /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
43455f757f3fSDimitry Andric         CXXConstructionKind::Complete, SourceRange());
43460b57cec5SDimitry Andric   }
43470b57cec5SDimitry Andric 
43480b57cec5SDimitry Andric   // Resolve overloaded function references.
43490b57cec5SDimitry Andric   if (Context.hasSameType(FromType, Context.OverloadTy)) {
43500b57cec5SDimitry Andric     DeclAccessPair Found;
43510b57cec5SDimitry Andric     FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType,
43520b57cec5SDimitry Andric                                                           true, Found);
43530b57cec5SDimitry Andric     if (!Fn)
43540b57cec5SDimitry Andric       return ExprError();
43550b57cec5SDimitry Andric 
43560b57cec5SDimitry Andric     if (DiagnoseUseOfDecl(Fn, From->getBeginLoc()))
43570b57cec5SDimitry Andric       return ExprError();
43580b57cec5SDimitry Andric 
43595f757f3fSDimitry Andric     ExprResult Res = FixOverloadedFunctionReference(From, Found, Fn);
43605f757f3fSDimitry Andric     if (Res.isInvalid())
43615f757f3fSDimitry Andric       return ExprError();
436281ad6265SDimitry Andric 
436381ad6265SDimitry Andric     // We might get back another placeholder expression if we resolved to a
436481ad6265SDimitry Andric     // builtin.
43655f757f3fSDimitry Andric     Res = CheckPlaceholderExpr(Res.get());
43665f757f3fSDimitry Andric     if (Res.isInvalid())
436781ad6265SDimitry Andric       return ExprError();
436881ad6265SDimitry Andric 
43695f757f3fSDimitry Andric     From = Res.get();
43700b57cec5SDimitry Andric     FromType = From->getType();
43710b57cec5SDimitry Andric   }
43720b57cec5SDimitry Andric 
43730b57cec5SDimitry Andric   // If we're converting to an atomic type, first convert to the corresponding
43740b57cec5SDimitry Andric   // non-atomic type.
43750b57cec5SDimitry Andric   QualType ToAtomicType;
43760b57cec5SDimitry Andric   if (const AtomicType *ToAtomic = ToType->getAs<AtomicType>()) {
43770b57cec5SDimitry Andric     ToAtomicType = ToType;
43780b57cec5SDimitry Andric     ToType = ToAtomic->getValueType();
43790b57cec5SDimitry Andric   }
43800b57cec5SDimitry Andric 
43810b57cec5SDimitry Andric   QualType InitialFromType = FromType;
43820b57cec5SDimitry Andric   // Perform the first implicit conversion.
43830b57cec5SDimitry Andric   switch (SCS.First) {
43840b57cec5SDimitry Andric   case ICK_Identity:
43850b57cec5SDimitry Andric     if (const AtomicType *FromAtomic = FromType->getAs<AtomicType>()) {
43860b57cec5SDimitry Andric       FromType = FromAtomic->getValueType().getUnqualifiedType();
43870b57cec5SDimitry Andric       From = ImplicitCastExpr::Create(Context, FromType, CK_AtomicToNonAtomic,
4388fe6060f1SDimitry Andric                                       From, /*BasePath=*/nullptr, VK_PRValue,
4389e8d8bef9SDimitry Andric                                       FPOptionsOverride());
43900b57cec5SDimitry Andric     }
43910b57cec5SDimitry Andric     break;
43920b57cec5SDimitry Andric 
43930b57cec5SDimitry Andric   case ICK_Lvalue_To_Rvalue: {
43940b57cec5SDimitry Andric     assert(From->getObjectKind() != OK_ObjCProperty);
43950b57cec5SDimitry Andric     ExprResult FromRes = DefaultLvalueConversion(From);
4396fe6060f1SDimitry Andric     if (FromRes.isInvalid())
4397fe6060f1SDimitry Andric       return ExprError();
4398fe6060f1SDimitry Andric 
43990b57cec5SDimitry Andric     From = FromRes.get();
44000b57cec5SDimitry Andric     FromType = From->getType();
44010b57cec5SDimitry Andric     break;
44020b57cec5SDimitry Andric   }
44030b57cec5SDimitry Andric 
44040b57cec5SDimitry Andric   case ICK_Array_To_Pointer:
44050b57cec5SDimitry Andric     FromType = Context.getArrayDecayedType(FromType);
4406fe6060f1SDimitry Andric     From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay, VK_PRValue,
4407fe6060f1SDimitry Andric                              /*BasePath=*/nullptr, CCK)
4408fe6060f1SDimitry Andric                .get();
44090b57cec5SDimitry Andric     break;
44100b57cec5SDimitry Andric 
44110b57cec5SDimitry Andric   case ICK_Function_To_Pointer:
44120b57cec5SDimitry Andric     FromType = Context.getPointerType(FromType);
44130b57cec5SDimitry Andric     From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay,
4414fe6060f1SDimitry Andric                              VK_PRValue, /*BasePath=*/nullptr, CCK)
4415fe6060f1SDimitry Andric                .get();
44160b57cec5SDimitry Andric     break;
44170b57cec5SDimitry Andric 
44180b57cec5SDimitry Andric   default:
44190b57cec5SDimitry Andric     llvm_unreachable("Improper first standard conversion");
44200b57cec5SDimitry Andric   }
44210b57cec5SDimitry Andric 
44220b57cec5SDimitry Andric   // Perform the second implicit conversion
44230b57cec5SDimitry Andric   switch (SCS.Second) {
44240b57cec5SDimitry Andric   case ICK_Identity:
44250b57cec5SDimitry Andric     // C++ [except.spec]p5:
44260b57cec5SDimitry Andric     //   [For] assignment to and initialization of pointers to functions,
44270b57cec5SDimitry Andric     //   pointers to member functions, and references to functions: the
44280b57cec5SDimitry Andric     //   target entity shall allow at least the exceptions allowed by the
44290b57cec5SDimitry Andric     //   source value in the assignment or initialization.
44300b57cec5SDimitry Andric     switch (Action) {
44310b57cec5SDimitry Andric     case AA_Assigning:
44320b57cec5SDimitry Andric     case AA_Initializing:
44330b57cec5SDimitry Andric       // Note, function argument passing and returning are initialization.
44340b57cec5SDimitry Andric     case AA_Passing:
44350b57cec5SDimitry Andric     case AA_Returning:
44360b57cec5SDimitry Andric     case AA_Sending:
44370b57cec5SDimitry Andric     case AA_Passing_CFAudited:
44380b57cec5SDimitry Andric       if (CheckExceptionSpecCompatibility(From, ToType))
44390b57cec5SDimitry Andric         return ExprError();
44400b57cec5SDimitry Andric       break;
44410b57cec5SDimitry Andric 
44420b57cec5SDimitry Andric     case AA_Casting:
44430b57cec5SDimitry Andric     case AA_Converting:
44440b57cec5SDimitry Andric       // Casts and implicit conversions are not initialization, so are not
44450b57cec5SDimitry Andric       // checked for exception specification mismatches.
44460b57cec5SDimitry Andric       break;
44470b57cec5SDimitry Andric     }
44480b57cec5SDimitry Andric     // Nothing else to do.
44490b57cec5SDimitry Andric     break;
44500b57cec5SDimitry Andric 
44510b57cec5SDimitry Andric   case ICK_Integral_Promotion:
44520b57cec5SDimitry Andric   case ICK_Integral_Conversion:
44530b57cec5SDimitry Andric     if (ToType->isBooleanType()) {
44540b57cec5SDimitry Andric       assert(FromType->castAs<EnumType>()->getDecl()->isFixed() &&
44550b57cec5SDimitry Andric              SCS.Second == ICK_Integral_Promotion &&
44560b57cec5SDimitry Andric              "only enums with fixed underlying type can promote to bool");
4457fe6060f1SDimitry Andric       From = ImpCastExprToType(From, ToType, CK_IntegralToBoolean, VK_PRValue,
4458fe6060f1SDimitry Andric                                /*BasePath=*/nullptr, CCK)
4459fe6060f1SDimitry Andric                  .get();
44600b57cec5SDimitry Andric     } else {
4461fe6060f1SDimitry Andric       From = ImpCastExprToType(From, ToType, CK_IntegralCast, VK_PRValue,
4462fe6060f1SDimitry Andric                                /*BasePath=*/nullptr, CCK)
4463fe6060f1SDimitry Andric                  .get();
44640b57cec5SDimitry Andric     }
44650b57cec5SDimitry Andric     break;
44660b57cec5SDimitry Andric 
44670b57cec5SDimitry Andric   case ICK_Floating_Promotion:
44680b57cec5SDimitry Andric   case ICK_Floating_Conversion:
4469fe6060f1SDimitry Andric     From = ImpCastExprToType(From, ToType, CK_FloatingCast, VK_PRValue,
4470fe6060f1SDimitry Andric                              /*BasePath=*/nullptr, CCK)
4471fe6060f1SDimitry Andric                .get();
44720b57cec5SDimitry Andric     break;
44730b57cec5SDimitry Andric 
44740b57cec5SDimitry Andric   case ICK_Complex_Promotion:
44750b57cec5SDimitry Andric   case ICK_Complex_Conversion: {
4476a7dea167SDimitry Andric     QualType FromEl = From->getType()->castAs<ComplexType>()->getElementType();
4477a7dea167SDimitry Andric     QualType ToEl = ToType->castAs<ComplexType>()->getElementType();
44780b57cec5SDimitry Andric     CastKind CK;
44790b57cec5SDimitry Andric     if (FromEl->isRealFloatingType()) {
44800b57cec5SDimitry Andric       if (ToEl->isRealFloatingType())
44810b57cec5SDimitry Andric         CK = CK_FloatingComplexCast;
44820b57cec5SDimitry Andric       else
44830b57cec5SDimitry Andric         CK = CK_FloatingComplexToIntegralComplex;
44840b57cec5SDimitry Andric     } else if (ToEl->isRealFloatingType()) {
44850b57cec5SDimitry Andric       CK = CK_IntegralComplexToFloatingComplex;
44860b57cec5SDimitry Andric     } else {
44870b57cec5SDimitry Andric       CK = CK_IntegralComplexCast;
44880b57cec5SDimitry Andric     }
4489fe6060f1SDimitry Andric     From = ImpCastExprToType(From, ToType, CK, VK_PRValue, /*BasePath=*/nullptr,
4490fe6060f1SDimitry Andric                              CCK)
4491fe6060f1SDimitry Andric                .get();
44920b57cec5SDimitry Andric     break;
44930b57cec5SDimitry Andric   }
44940b57cec5SDimitry Andric 
44950b57cec5SDimitry Andric   case ICK_Floating_Integral:
44960b57cec5SDimitry Andric     if (ToType->isRealFloatingType())
4497fe6060f1SDimitry Andric       From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue,
4498fe6060f1SDimitry Andric                                /*BasePath=*/nullptr, CCK)
4499fe6060f1SDimitry Andric                  .get();
45000b57cec5SDimitry Andric     else
4501fe6060f1SDimitry Andric       From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral, VK_PRValue,
4502fe6060f1SDimitry Andric                                /*BasePath=*/nullptr, CCK)
4503fe6060f1SDimitry Andric                  .get();
45040b57cec5SDimitry Andric     break;
45050b57cec5SDimitry Andric 
45065f757f3fSDimitry Andric   case ICK_Fixed_Point_Conversion:
45075f757f3fSDimitry Andric     assert((FromType->isFixedPointType() || ToType->isFixedPointType()) &&
45085f757f3fSDimitry Andric            "Attempting implicit fixed point conversion without a fixed "
45095f757f3fSDimitry Andric            "point operand");
45105f757f3fSDimitry Andric     if (FromType->isFloatingType())
45115f757f3fSDimitry Andric       From = ImpCastExprToType(From, ToType, CK_FloatingToFixedPoint,
45125f757f3fSDimitry Andric                                VK_PRValue,
45135f757f3fSDimitry Andric                                /*BasePath=*/nullptr, CCK).get();
45145f757f3fSDimitry Andric     else if (ToType->isFloatingType())
45155f757f3fSDimitry Andric       From = ImpCastExprToType(From, ToType, CK_FixedPointToFloating,
45165f757f3fSDimitry Andric                                VK_PRValue,
45175f757f3fSDimitry Andric                                /*BasePath=*/nullptr, CCK).get();
45185f757f3fSDimitry Andric     else if (FromType->isIntegralType(Context))
45195f757f3fSDimitry Andric       From = ImpCastExprToType(From, ToType, CK_IntegralToFixedPoint,
45205f757f3fSDimitry Andric                                VK_PRValue,
45215f757f3fSDimitry Andric                                /*BasePath=*/nullptr, CCK).get();
45225f757f3fSDimitry Andric     else if (ToType->isIntegralType(Context))
45235f757f3fSDimitry Andric       From = ImpCastExprToType(From, ToType, CK_FixedPointToIntegral,
45245f757f3fSDimitry Andric                                VK_PRValue,
45255f757f3fSDimitry Andric                                /*BasePath=*/nullptr, CCK).get();
45265f757f3fSDimitry Andric     else if (ToType->isBooleanType())
45275f757f3fSDimitry Andric       From = ImpCastExprToType(From, ToType, CK_FixedPointToBoolean,
45285f757f3fSDimitry Andric                                VK_PRValue,
45295f757f3fSDimitry Andric                                /*BasePath=*/nullptr, CCK).get();
45305f757f3fSDimitry Andric     else
45315f757f3fSDimitry Andric       From = ImpCastExprToType(From, ToType, CK_FixedPointCast,
45325f757f3fSDimitry Andric                                VK_PRValue,
45335f757f3fSDimitry Andric                                /*BasePath=*/nullptr, CCK).get();
45345f757f3fSDimitry Andric     break;
45355f757f3fSDimitry Andric 
45360b57cec5SDimitry Andric   case ICK_Compatible_Conversion:
4537f13e6193SDimitry Andric     From = ImpCastExprToType(From, ToType, CK_NoOp, From->getValueKind(),
4538f13e6193SDimitry Andric                              /*BasePath=*/nullptr, CCK).get();
45390b57cec5SDimitry Andric     break;
45400b57cec5SDimitry Andric 
45410b57cec5SDimitry Andric   case ICK_Writeback_Conversion:
45420b57cec5SDimitry Andric   case ICK_Pointer_Conversion: {
45430b57cec5SDimitry Andric     if (SCS.IncompatibleObjC && Action != AA_Casting) {
45440b57cec5SDimitry Andric       // Diagnose incompatible Objective-C conversions
45450b57cec5SDimitry Andric       if (Action == AA_Initializing || Action == AA_Assigning)
45460b57cec5SDimitry Andric         Diag(From->getBeginLoc(),
45470b57cec5SDimitry Andric              diag::ext_typecheck_convert_incompatible_pointer)
45480b57cec5SDimitry Andric             << ToType << From->getType() << Action << From->getSourceRange()
45490b57cec5SDimitry Andric             << 0;
45500b57cec5SDimitry Andric       else
45510b57cec5SDimitry Andric         Diag(From->getBeginLoc(),
45520b57cec5SDimitry Andric              diag::ext_typecheck_convert_incompatible_pointer)
45530b57cec5SDimitry Andric             << From->getType() << ToType << Action << From->getSourceRange()
45540b57cec5SDimitry Andric             << 0;
45550b57cec5SDimitry Andric 
45560b57cec5SDimitry Andric       if (From->getType()->isObjCObjectPointerType() &&
45570b57cec5SDimitry Andric           ToType->isObjCObjectPointerType())
45580b57cec5SDimitry Andric         EmitRelatedResultTypeNote(From);
45590b57cec5SDimitry Andric     } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
45600b57cec5SDimitry Andric                !CheckObjCARCUnavailableWeakConversion(ToType,
45610b57cec5SDimitry Andric                                                       From->getType())) {
45620b57cec5SDimitry Andric       if (Action == AA_Initializing)
45630b57cec5SDimitry Andric         Diag(From->getBeginLoc(), diag::err_arc_weak_unavailable_assign);
45640b57cec5SDimitry Andric       else
45650b57cec5SDimitry Andric         Diag(From->getBeginLoc(), diag::err_arc_convesion_of_weak_unavailable)
45660b57cec5SDimitry Andric             << (Action == AA_Casting) << From->getType() << ToType
45670b57cec5SDimitry Andric             << From->getSourceRange();
45680b57cec5SDimitry Andric     }
45690b57cec5SDimitry Andric 
4570480093f4SDimitry Andric     // Defer address space conversion to the third conversion.
4571480093f4SDimitry Andric     QualType FromPteeType = From->getType()->getPointeeType();
4572480093f4SDimitry Andric     QualType ToPteeType = ToType->getPointeeType();
4573480093f4SDimitry Andric     QualType NewToType = ToType;
4574480093f4SDimitry Andric     if (!FromPteeType.isNull() && !ToPteeType.isNull() &&
4575480093f4SDimitry Andric         FromPteeType.getAddressSpace() != ToPteeType.getAddressSpace()) {
4576480093f4SDimitry Andric       NewToType = Context.removeAddrSpaceQualType(ToPteeType);
4577480093f4SDimitry Andric       NewToType = Context.getAddrSpaceQualType(NewToType,
4578480093f4SDimitry Andric                                                FromPteeType.getAddressSpace());
4579480093f4SDimitry Andric       if (ToType->isObjCObjectPointerType())
4580480093f4SDimitry Andric         NewToType = Context.getObjCObjectPointerType(NewToType);
4581480093f4SDimitry Andric       else if (ToType->isBlockPointerType())
4582480093f4SDimitry Andric         NewToType = Context.getBlockPointerType(NewToType);
4583480093f4SDimitry Andric       else
4584480093f4SDimitry Andric         NewToType = Context.getPointerType(NewToType);
4585480093f4SDimitry Andric     }
4586480093f4SDimitry Andric 
45870b57cec5SDimitry Andric     CastKind Kind;
45880b57cec5SDimitry Andric     CXXCastPath BasePath;
4589480093f4SDimitry Andric     if (CheckPointerConversion(From, NewToType, Kind, BasePath, CStyle))
45900b57cec5SDimitry Andric       return ExprError();
45910b57cec5SDimitry Andric 
45920b57cec5SDimitry Andric     // Make sure we extend blocks if necessary.
45930b57cec5SDimitry Andric     // FIXME: doing this here is really ugly.
45940b57cec5SDimitry Andric     if (Kind == CK_BlockPointerToObjCPointerCast) {
45950b57cec5SDimitry Andric       ExprResult E = From;
45960b57cec5SDimitry Andric       (void) PrepareCastToObjCObjectPointer(E);
45970b57cec5SDimitry Andric       From = E.get();
45980b57cec5SDimitry Andric     }
45990b57cec5SDimitry Andric     if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
4600480093f4SDimitry Andric       CheckObjCConversion(SourceRange(), NewToType, From, CCK);
4601fe6060f1SDimitry Andric     From = ImpCastExprToType(From, NewToType, Kind, VK_PRValue, &BasePath, CCK)
46020b57cec5SDimitry Andric                .get();
46030b57cec5SDimitry Andric     break;
46040b57cec5SDimitry Andric   }
46050b57cec5SDimitry Andric 
46060b57cec5SDimitry Andric   case ICK_Pointer_Member: {
46070b57cec5SDimitry Andric     CastKind Kind;
46080b57cec5SDimitry Andric     CXXCastPath BasePath;
46090b57cec5SDimitry Andric     if (CheckMemberPointerConversion(From, ToType, Kind, BasePath, CStyle))
46100b57cec5SDimitry Andric       return ExprError();
46110b57cec5SDimitry Andric     if (CheckExceptionSpecCompatibility(From, ToType))
46120b57cec5SDimitry Andric       return ExprError();
46130b57cec5SDimitry Andric 
46140b57cec5SDimitry Andric     // We may not have been able to figure out what this member pointer resolved
46150b57cec5SDimitry Andric     // to up until this exact point.  Attempt to lock-in it's inheritance model.
46160b57cec5SDimitry Andric     if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
46170b57cec5SDimitry Andric       (void)isCompleteType(From->getExprLoc(), From->getType());
46180b57cec5SDimitry Andric       (void)isCompleteType(From->getExprLoc(), ToType);
46190b57cec5SDimitry Andric     }
46200b57cec5SDimitry Andric 
4621fe6060f1SDimitry Andric     From =
4622fe6060f1SDimitry Andric         ImpCastExprToType(From, ToType, Kind, VK_PRValue, &BasePath, CCK).get();
46230b57cec5SDimitry Andric     break;
46240b57cec5SDimitry Andric   }
46250b57cec5SDimitry Andric 
46260b57cec5SDimitry Andric   case ICK_Boolean_Conversion:
46270b57cec5SDimitry Andric     // Perform half-to-boolean conversion via float.
46280b57cec5SDimitry Andric     if (From->getType()->isHalfType()) {
46290b57cec5SDimitry Andric       From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).get();
46300b57cec5SDimitry Andric       FromType = Context.FloatTy;
46310b57cec5SDimitry Andric     }
46320b57cec5SDimitry Andric 
46330b57cec5SDimitry Andric     From = ImpCastExprToType(From, Context.BoolTy,
4634fe6060f1SDimitry Andric                              ScalarTypeToBooleanCastKind(FromType), VK_PRValue,
4635fe6060f1SDimitry Andric                              /*BasePath=*/nullptr, CCK)
4636fe6060f1SDimitry Andric                .get();
46370b57cec5SDimitry Andric     break;
46380b57cec5SDimitry Andric 
46390b57cec5SDimitry Andric   case ICK_Derived_To_Base: {
46400b57cec5SDimitry Andric     CXXCastPath BasePath;
46410b57cec5SDimitry Andric     if (CheckDerivedToBaseConversion(
46420b57cec5SDimitry Andric             From->getType(), ToType.getNonReferenceType(), From->getBeginLoc(),
46430b57cec5SDimitry Andric             From->getSourceRange(), &BasePath, CStyle))
46440b57cec5SDimitry Andric       return ExprError();
46450b57cec5SDimitry Andric 
46460b57cec5SDimitry Andric     From = ImpCastExprToType(From, ToType.getNonReferenceType(),
46470b57cec5SDimitry Andric                       CK_DerivedToBase, From->getValueKind(),
46480b57cec5SDimitry Andric                       &BasePath, CCK).get();
46490b57cec5SDimitry Andric     break;
46500b57cec5SDimitry Andric   }
46510b57cec5SDimitry Andric 
46520b57cec5SDimitry Andric   case ICK_Vector_Conversion:
4653fe6060f1SDimitry Andric     From = ImpCastExprToType(From, ToType, CK_BitCast, VK_PRValue,
4654fe6060f1SDimitry Andric                              /*BasePath=*/nullptr, CCK)
4655fe6060f1SDimitry Andric                .get();
46560b57cec5SDimitry Andric     break;
46570b57cec5SDimitry Andric 
4658e8d8bef9SDimitry Andric   case ICK_SVE_Vector_Conversion:
465906c3fb27SDimitry Andric   case ICK_RVV_Vector_Conversion:
4660fe6060f1SDimitry Andric     From = ImpCastExprToType(From, ToType, CK_BitCast, VK_PRValue,
4661e8d8bef9SDimitry Andric                              /*BasePath=*/nullptr, CCK)
4662e8d8bef9SDimitry Andric                .get();
4663e8d8bef9SDimitry Andric     break;
4664e8d8bef9SDimitry Andric 
46650b57cec5SDimitry Andric   case ICK_Vector_Splat: {
46660b57cec5SDimitry Andric     // Vector splat from any arithmetic type to a vector.
46670b57cec5SDimitry Andric     Expr *Elem = prepareVectorSplat(ToType, From).get();
4668fe6060f1SDimitry Andric     From = ImpCastExprToType(Elem, ToType, CK_VectorSplat, VK_PRValue,
4669fe6060f1SDimitry Andric                              /*BasePath=*/nullptr, CCK)
4670fe6060f1SDimitry Andric                .get();
46710b57cec5SDimitry Andric     break;
46720b57cec5SDimitry Andric   }
46730b57cec5SDimitry Andric 
46740b57cec5SDimitry Andric   case ICK_Complex_Real:
46750b57cec5SDimitry Andric     // Case 1.  x -> _Complex y
46760b57cec5SDimitry Andric     if (const ComplexType *ToComplex = ToType->getAs<ComplexType>()) {
46770b57cec5SDimitry Andric       QualType ElType = ToComplex->getElementType();
46780b57cec5SDimitry Andric       bool isFloatingComplex = ElType->isRealFloatingType();
46790b57cec5SDimitry Andric 
46800b57cec5SDimitry Andric       // x -> y
46810b57cec5SDimitry Andric       if (Context.hasSameUnqualifiedType(ElType, From->getType())) {
46820b57cec5SDimitry Andric         // do nothing
46830b57cec5SDimitry Andric       } else if (From->getType()->isRealFloatingType()) {
46840b57cec5SDimitry Andric         From = ImpCastExprToType(From, ElType,
46850b57cec5SDimitry Andric                 isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).get();
46860b57cec5SDimitry Andric       } else {
46870b57cec5SDimitry Andric         assert(From->getType()->isIntegerType());
46880b57cec5SDimitry Andric         From = ImpCastExprToType(From, ElType,
46890b57cec5SDimitry Andric                 isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).get();
46900b57cec5SDimitry Andric       }
46910b57cec5SDimitry Andric       // y -> _Complex y
46920b57cec5SDimitry Andric       From = ImpCastExprToType(From, ToType,
46930b57cec5SDimitry Andric                    isFloatingComplex ? CK_FloatingRealToComplex
46940b57cec5SDimitry Andric                                      : CK_IntegralRealToComplex).get();
46950b57cec5SDimitry Andric 
46960b57cec5SDimitry Andric     // Case 2.  _Complex x -> y
46970b57cec5SDimitry Andric     } else {
46985ffd83dbSDimitry Andric       auto *FromComplex = From->getType()->castAs<ComplexType>();
46990b57cec5SDimitry Andric       QualType ElType = FromComplex->getElementType();
47000b57cec5SDimitry Andric       bool isFloatingComplex = ElType->isRealFloatingType();
47010b57cec5SDimitry Andric 
47020b57cec5SDimitry Andric       // _Complex x -> x
47030b57cec5SDimitry Andric       From = ImpCastExprToType(From, ElType,
47040b57cec5SDimitry Andric                                isFloatingComplex ? CK_FloatingComplexToReal
47050b57cec5SDimitry Andric                                                  : CK_IntegralComplexToReal,
4706fe6060f1SDimitry Andric                                VK_PRValue, /*BasePath=*/nullptr, CCK)
4707fe6060f1SDimitry Andric                  .get();
47080b57cec5SDimitry Andric 
47090b57cec5SDimitry Andric       // x -> y
47100b57cec5SDimitry Andric       if (Context.hasSameUnqualifiedType(ElType, ToType)) {
47110b57cec5SDimitry Andric         // do nothing
47120b57cec5SDimitry Andric       } else if (ToType->isRealFloatingType()) {
47130b57cec5SDimitry Andric         From = ImpCastExprToType(From, ToType,
4714fe6060f1SDimitry Andric                                  isFloatingComplex ? CK_FloatingCast
4715fe6060f1SDimitry Andric                                                    : CK_IntegralToFloating,
4716fe6060f1SDimitry Andric                                  VK_PRValue, /*BasePath=*/nullptr, CCK)
4717fe6060f1SDimitry Andric                    .get();
47180b57cec5SDimitry Andric       } else {
47190b57cec5SDimitry Andric         assert(ToType->isIntegerType());
47200b57cec5SDimitry Andric         From = ImpCastExprToType(From, ToType,
4721fe6060f1SDimitry Andric                                  isFloatingComplex ? CK_FloatingToIntegral
4722fe6060f1SDimitry Andric                                                    : CK_IntegralCast,
4723fe6060f1SDimitry Andric                                  VK_PRValue, /*BasePath=*/nullptr, CCK)
4724fe6060f1SDimitry Andric                    .get();
47250b57cec5SDimitry Andric       }
47260b57cec5SDimitry Andric     }
47270b57cec5SDimitry Andric     break;
47280b57cec5SDimitry Andric 
47290b57cec5SDimitry Andric   case ICK_Block_Pointer_Conversion: {
47300b57cec5SDimitry Andric     LangAS AddrSpaceL =
47310b57cec5SDimitry Andric         ToType->castAs<BlockPointerType>()->getPointeeType().getAddressSpace();
47320b57cec5SDimitry Andric     LangAS AddrSpaceR =
47330b57cec5SDimitry Andric         FromType->castAs<BlockPointerType>()->getPointeeType().getAddressSpace();
47340b57cec5SDimitry Andric     assert(Qualifiers::isAddressSpaceSupersetOf(AddrSpaceL, AddrSpaceR) &&
47350b57cec5SDimitry Andric            "Invalid cast");
47360b57cec5SDimitry Andric     CastKind Kind =
47370b57cec5SDimitry Andric         AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast;
47380b57cec5SDimitry Andric     From = ImpCastExprToType(From, ToType.getUnqualifiedType(), Kind,
4739fe6060f1SDimitry Andric                              VK_PRValue, /*BasePath=*/nullptr, CCK)
4740fe6060f1SDimitry Andric                .get();
47410b57cec5SDimitry Andric     break;
47420b57cec5SDimitry Andric   }
47430b57cec5SDimitry Andric 
47440b57cec5SDimitry Andric   case ICK_TransparentUnionConversion: {
47450b57cec5SDimitry Andric     ExprResult FromRes = From;
47460b57cec5SDimitry Andric     Sema::AssignConvertType ConvTy =
47470b57cec5SDimitry Andric       CheckTransparentUnionArgumentConstraints(ToType, FromRes);
47480b57cec5SDimitry Andric     if (FromRes.isInvalid())
47490b57cec5SDimitry Andric       return ExprError();
47500b57cec5SDimitry Andric     From = FromRes.get();
47510b57cec5SDimitry Andric     assert ((ConvTy == Sema::Compatible) &&
47520b57cec5SDimitry Andric             "Improper transparent union conversion");
47530b57cec5SDimitry Andric     (void)ConvTy;
47540b57cec5SDimitry Andric     break;
47550b57cec5SDimitry Andric   }
47560b57cec5SDimitry Andric 
47570b57cec5SDimitry Andric   case ICK_Zero_Event_Conversion:
47580b57cec5SDimitry Andric   case ICK_Zero_Queue_Conversion:
47590b57cec5SDimitry Andric     From = ImpCastExprToType(From, ToType,
47600b57cec5SDimitry Andric                              CK_ZeroToOCLOpaqueType,
47610b57cec5SDimitry Andric                              From->getValueKind()).get();
47620b57cec5SDimitry Andric     break;
47630b57cec5SDimitry Andric 
47640b57cec5SDimitry Andric   case ICK_Lvalue_To_Rvalue:
47650b57cec5SDimitry Andric   case ICK_Array_To_Pointer:
47660b57cec5SDimitry Andric   case ICK_Function_To_Pointer:
47670b57cec5SDimitry Andric   case ICK_Function_Conversion:
47680b57cec5SDimitry Andric   case ICK_Qualification:
47690b57cec5SDimitry Andric   case ICK_Num_Conversion_Kinds:
47700b57cec5SDimitry Andric   case ICK_C_Only_Conversion:
47710b57cec5SDimitry Andric   case ICK_Incompatible_Pointer_Conversion:
47720b57cec5SDimitry Andric     llvm_unreachable("Improper second standard conversion");
47730b57cec5SDimitry Andric   }
47740b57cec5SDimitry Andric 
47750b57cec5SDimitry Andric   switch (SCS.Third) {
47760b57cec5SDimitry Andric   case ICK_Identity:
47770b57cec5SDimitry Andric     // Nothing to do.
47780b57cec5SDimitry Andric     break;
47790b57cec5SDimitry Andric 
47800b57cec5SDimitry Andric   case ICK_Function_Conversion:
47810b57cec5SDimitry Andric     // If both sides are functions (or pointers/references to them), there could
47820b57cec5SDimitry Andric     // be incompatible exception declarations.
47830b57cec5SDimitry Andric     if (CheckExceptionSpecCompatibility(From, ToType))
47840b57cec5SDimitry Andric       return ExprError();
47850b57cec5SDimitry Andric 
4786fe6060f1SDimitry Andric     From = ImpCastExprToType(From, ToType, CK_NoOp, VK_PRValue,
4787fe6060f1SDimitry Andric                              /*BasePath=*/nullptr, CCK)
4788fe6060f1SDimitry Andric                .get();
47890b57cec5SDimitry Andric     break;
47900b57cec5SDimitry Andric 
47910b57cec5SDimitry Andric   case ICK_Qualification: {
4792f13e6193SDimitry Andric     ExprValueKind VK = From->getValueKind();
47930b57cec5SDimitry Andric     CastKind CK = CK_NoOp;
47940b57cec5SDimitry Andric 
47950b57cec5SDimitry Andric     if (ToType->isReferenceType() &&
47960b57cec5SDimitry Andric         ToType->getPointeeType().getAddressSpace() !=
47970b57cec5SDimitry Andric             From->getType().getAddressSpace())
47980b57cec5SDimitry Andric       CK = CK_AddressSpaceConversion;
47990b57cec5SDimitry Andric 
48000b57cec5SDimitry Andric     if (ToType->isPointerType() &&
48010b57cec5SDimitry Andric         ToType->getPointeeType().getAddressSpace() !=
48020b57cec5SDimitry Andric             From->getType()->getPointeeType().getAddressSpace())
48030b57cec5SDimitry Andric       CK = CK_AddressSpaceConversion;
48040b57cec5SDimitry Andric 
480581ad6265SDimitry Andric     if (!isCast(CCK) &&
480681ad6265SDimitry Andric         !ToType->getPointeeType().getQualifiers().hasUnaligned() &&
480781ad6265SDimitry Andric         From->getType()->getPointeeType().getQualifiers().hasUnaligned()) {
480881ad6265SDimitry Andric       Diag(From->getBeginLoc(), diag::warn_imp_cast_drops_unaligned)
480981ad6265SDimitry Andric           << InitialFromType << ToType;
481081ad6265SDimitry Andric     }
481181ad6265SDimitry Andric 
48120b57cec5SDimitry Andric     From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context), CK, VK,
48130b57cec5SDimitry Andric                              /*BasePath=*/nullptr, CCK)
48140b57cec5SDimitry Andric                .get();
48150b57cec5SDimitry Andric 
48160b57cec5SDimitry Andric     if (SCS.DeprecatedStringLiteralToCharPtr &&
48170b57cec5SDimitry Andric         !getLangOpts().WritableStrings) {
48180b57cec5SDimitry Andric       Diag(From->getBeginLoc(),
48190b57cec5SDimitry Andric            getLangOpts().CPlusPlus11
48200b57cec5SDimitry Andric                ? diag::ext_deprecated_string_literal_conversion
48210b57cec5SDimitry Andric                : diag::warn_deprecated_string_literal_conversion)
48220b57cec5SDimitry Andric           << ToType.getNonReferenceType();
48230b57cec5SDimitry Andric     }
48240b57cec5SDimitry Andric 
48250b57cec5SDimitry Andric     break;
48260b57cec5SDimitry Andric   }
48270b57cec5SDimitry Andric 
48280b57cec5SDimitry Andric   default:
48290b57cec5SDimitry Andric     llvm_unreachable("Improper third standard conversion");
48300b57cec5SDimitry Andric   }
48310b57cec5SDimitry Andric 
48320b57cec5SDimitry Andric   // If this conversion sequence involved a scalar -> atomic conversion, perform
48330b57cec5SDimitry Andric   // that conversion now.
48340b57cec5SDimitry Andric   if (!ToAtomicType.isNull()) {
48350b57cec5SDimitry Andric     assert(Context.hasSameType(
48360b57cec5SDimitry Andric         ToAtomicType->castAs<AtomicType>()->getValueType(), From->getType()));
48370b57cec5SDimitry Andric     From = ImpCastExprToType(From, ToAtomicType, CK_NonAtomicToAtomic,
4838fe6060f1SDimitry Andric                              VK_PRValue, nullptr, CCK)
4839fe6060f1SDimitry Andric                .get();
48400b57cec5SDimitry Andric   }
48410b57cec5SDimitry Andric 
48425ffd83dbSDimitry Andric   // Materialize a temporary if we're implicitly converting to a reference
48435ffd83dbSDimitry Andric   // type. This is not required by the C++ rules but is necessary to maintain
48445ffd83dbSDimitry Andric   // AST invariants.
4845fe6060f1SDimitry Andric   if (ToType->isReferenceType() && From->isPRValue()) {
48465ffd83dbSDimitry Andric     ExprResult Res = TemporaryMaterializationConversion(From);
48475ffd83dbSDimitry Andric     if (Res.isInvalid())
48485ffd83dbSDimitry Andric       return ExprError();
48495ffd83dbSDimitry Andric     From = Res.get();
48505ffd83dbSDimitry Andric   }
48515ffd83dbSDimitry Andric 
48520b57cec5SDimitry Andric   // If this conversion sequence succeeded and involved implicitly converting a
48530b57cec5SDimitry Andric   // _Nullable type to a _Nonnull one, complain.
48540b57cec5SDimitry Andric   if (!isCast(CCK))
48550b57cec5SDimitry Andric     diagnoseNullableToNonnullConversion(ToType, InitialFromType,
48560b57cec5SDimitry Andric                                         From->getBeginLoc());
48570b57cec5SDimitry Andric 
48580b57cec5SDimitry Andric   return From;
48590b57cec5SDimitry Andric }
48600b57cec5SDimitry Andric 
48610b57cec5SDimitry Andric /// Check the completeness of a type in a unary type trait.
48620b57cec5SDimitry Andric ///
48630b57cec5SDimitry Andric /// If the particular type trait requires a complete type, tries to complete
48640b57cec5SDimitry Andric /// it. If completing the type fails, a diagnostic is emitted and false
48650b57cec5SDimitry Andric /// returned. If completing the type succeeds or no completion was required,
48660b57cec5SDimitry Andric /// returns true.
CheckUnaryTypeTraitTypeCompleteness(Sema & S,TypeTrait UTT,SourceLocation Loc,QualType ArgTy)48670b57cec5SDimitry Andric static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
48680b57cec5SDimitry Andric                                                 SourceLocation Loc,
48690b57cec5SDimitry Andric                                                 QualType ArgTy) {
48700b57cec5SDimitry Andric   // C++0x [meta.unary.prop]p3:
48710b57cec5SDimitry Andric   //   For all of the class templates X declared in this Clause, instantiating
48720b57cec5SDimitry Andric   //   that template with a template argument that is a class template
48730b57cec5SDimitry Andric   //   specialization may result in the implicit instantiation of the template
48740b57cec5SDimitry Andric   //   argument if and only if the semantics of X require that the argument
48750b57cec5SDimitry Andric   //   must be a complete type.
48760b57cec5SDimitry Andric   // We apply this rule to all the type trait expressions used to implement
48770b57cec5SDimitry Andric   // these class templates. We also try to follow any GCC documented behavior
48780b57cec5SDimitry Andric   // in these expressions to ensure portability of standard libraries.
48790b57cec5SDimitry Andric   switch (UTT) {
48800b57cec5SDimitry Andric   default: llvm_unreachable("not a UTT");
48810b57cec5SDimitry Andric     // is_complete_type somewhat obviously cannot require a complete type.
48820b57cec5SDimitry Andric   case UTT_IsCompleteType:
48830b57cec5SDimitry Andric     // Fall-through
48840b57cec5SDimitry Andric 
48850b57cec5SDimitry Andric     // These traits are modeled on the type predicates in C++0x
48860b57cec5SDimitry Andric     // [meta.unary.cat] and [meta.unary.comp]. They are not specified as
48870b57cec5SDimitry Andric     // requiring a complete type, as whether or not they return true cannot be
48880b57cec5SDimitry Andric     // impacted by the completeness of the type.
48890b57cec5SDimitry Andric   case UTT_IsVoid:
48900b57cec5SDimitry Andric   case UTT_IsIntegral:
48910b57cec5SDimitry Andric   case UTT_IsFloatingPoint:
48920b57cec5SDimitry Andric   case UTT_IsArray:
4893bdd1243dSDimitry Andric   case UTT_IsBoundedArray:
48940b57cec5SDimitry Andric   case UTT_IsPointer:
4895bdd1243dSDimitry Andric   case UTT_IsNullPointer:
4896bdd1243dSDimitry Andric   case UTT_IsReferenceable:
48970b57cec5SDimitry Andric   case UTT_IsLvalueReference:
48980b57cec5SDimitry Andric   case UTT_IsRvalueReference:
48990b57cec5SDimitry Andric   case UTT_IsMemberFunctionPointer:
49000b57cec5SDimitry Andric   case UTT_IsMemberObjectPointer:
49010b57cec5SDimitry Andric   case UTT_IsEnum:
4902bdd1243dSDimitry Andric   case UTT_IsScopedEnum:
49030b57cec5SDimitry Andric   case UTT_IsUnion:
49040b57cec5SDimitry Andric   case UTT_IsClass:
49050b57cec5SDimitry Andric   case UTT_IsFunction:
49060b57cec5SDimitry Andric   case UTT_IsReference:
49070b57cec5SDimitry Andric   case UTT_IsArithmetic:
49080b57cec5SDimitry Andric   case UTT_IsFundamental:
49090b57cec5SDimitry Andric   case UTT_IsObject:
49100b57cec5SDimitry Andric   case UTT_IsScalar:
49110b57cec5SDimitry Andric   case UTT_IsCompound:
49120b57cec5SDimitry Andric   case UTT_IsMemberPointer:
49130b57cec5SDimitry Andric     // Fall-through
49140b57cec5SDimitry Andric 
49150b57cec5SDimitry Andric     // These traits are modeled on type predicates in C++0x [meta.unary.prop]
49160b57cec5SDimitry Andric     // which requires some of its traits to have the complete type. However,
49170b57cec5SDimitry Andric     // the completeness of the type cannot impact these traits' semantics, and
49180b57cec5SDimitry Andric     // so they don't require it. This matches the comments on these traits in
49190b57cec5SDimitry Andric     // Table 49.
49200b57cec5SDimitry Andric   case UTT_IsConst:
49210b57cec5SDimitry Andric   case UTT_IsVolatile:
49220b57cec5SDimitry Andric   case UTT_IsSigned:
4923bdd1243dSDimitry Andric   case UTT_IsUnboundedArray:
49240b57cec5SDimitry Andric   case UTT_IsUnsigned:
49250b57cec5SDimitry Andric 
49260b57cec5SDimitry Andric   // This type trait always returns false, checking the type is moot.
49270b57cec5SDimitry Andric   case UTT_IsInterfaceClass:
49280b57cec5SDimitry Andric     return true;
49290b57cec5SDimitry Andric 
49300b57cec5SDimitry Andric   // C++14 [meta.unary.prop]:
49310b57cec5SDimitry Andric   //   If T is a non-union class type, T shall be a complete type.
49320b57cec5SDimitry Andric   case UTT_IsEmpty:
49330b57cec5SDimitry Andric   case UTT_IsPolymorphic:
49340b57cec5SDimitry Andric   case UTT_IsAbstract:
49350b57cec5SDimitry Andric     if (const auto *RD = ArgTy->getAsCXXRecordDecl())
49360b57cec5SDimitry Andric       if (!RD->isUnion())
49370b57cec5SDimitry Andric         return !S.RequireCompleteType(
49380b57cec5SDimitry Andric             Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
49390b57cec5SDimitry Andric     return true;
49400b57cec5SDimitry Andric 
49410b57cec5SDimitry Andric   // C++14 [meta.unary.prop]:
49420b57cec5SDimitry Andric   //   If T is a class type, T shall be a complete type.
49430b57cec5SDimitry Andric   case UTT_IsFinal:
49440b57cec5SDimitry Andric   case UTT_IsSealed:
49450b57cec5SDimitry Andric     if (ArgTy->getAsCXXRecordDecl())
49460b57cec5SDimitry Andric       return !S.RequireCompleteType(
49470b57cec5SDimitry Andric           Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
49480b57cec5SDimitry Andric     return true;
49490b57cec5SDimitry Andric 
4950bdd1243dSDimitry Andric   // LWG3823: T shall be an array type, a complete type, or cv void.
4951bdd1243dSDimitry Andric   case UTT_IsAggregate:
4952bdd1243dSDimitry Andric     if (ArgTy->isArrayType() || ArgTy->isVoidType())
4953bdd1243dSDimitry Andric       return true;
4954bdd1243dSDimitry Andric 
4955bdd1243dSDimitry Andric     return !S.RequireCompleteType(
4956bdd1243dSDimitry Andric         Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
4957bdd1243dSDimitry Andric 
49580b57cec5SDimitry Andric   // C++1z [meta.unary.prop]:
49590b57cec5SDimitry Andric   //   remove_all_extents_t<T> shall be a complete type or cv void.
49600b57cec5SDimitry Andric   case UTT_IsTrivial:
49610b57cec5SDimitry Andric   case UTT_IsTriviallyCopyable:
49620b57cec5SDimitry Andric   case UTT_IsStandardLayout:
49630b57cec5SDimitry Andric   case UTT_IsPOD:
49640b57cec5SDimitry Andric   case UTT_IsLiteral:
496506c3fb27SDimitry Andric   // By analogy, is_trivially_relocatable and is_trivially_equality_comparable
496606c3fb27SDimitry Andric   // impose the same constraints.
496781ad6265SDimitry Andric   case UTT_IsTriviallyRelocatable:
496806c3fb27SDimitry Andric   case UTT_IsTriviallyEqualityComparable:
496906c3fb27SDimitry Andric   case UTT_CanPassInRegs:
49700b57cec5SDimitry Andric   // Per the GCC type traits documentation, T shall be a complete type, cv void,
49710b57cec5SDimitry Andric   // or an array of unknown bound. But GCC actually imposes the same constraints
49720b57cec5SDimitry Andric   // as above.
49730b57cec5SDimitry Andric   case UTT_HasNothrowAssign:
49740b57cec5SDimitry Andric   case UTT_HasNothrowMoveAssign:
49750b57cec5SDimitry Andric   case UTT_HasNothrowConstructor:
49760b57cec5SDimitry Andric   case UTT_HasNothrowCopy:
49770b57cec5SDimitry Andric   case UTT_HasTrivialAssign:
49780b57cec5SDimitry Andric   case UTT_HasTrivialMoveAssign:
49790b57cec5SDimitry Andric   case UTT_HasTrivialDefaultConstructor:
49800b57cec5SDimitry Andric   case UTT_HasTrivialMoveConstructor:
49810b57cec5SDimitry Andric   case UTT_HasTrivialCopy:
49820b57cec5SDimitry Andric   case UTT_HasTrivialDestructor:
49830b57cec5SDimitry Andric   case UTT_HasVirtualDestructor:
49840b57cec5SDimitry Andric     ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);
4985bdd1243dSDimitry Andric     [[fallthrough]];
49860b57cec5SDimitry Andric 
49870b57cec5SDimitry Andric   // C++1z [meta.unary.prop]:
49880b57cec5SDimitry Andric   //   T shall be a complete type, cv void, or an array of unknown bound.
49890b57cec5SDimitry Andric   case UTT_IsDestructible:
49900b57cec5SDimitry Andric   case UTT_IsNothrowDestructible:
49910b57cec5SDimitry Andric   case UTT_IsTriviallyDestructible:
49920b57cec5SDimitry Andric   case UTT_HasUniqueObjectRepresentations:
49930b57cec5SDimitry Andric     if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
49940b57cec5SDimitry Andric       return true;
49950b57cec5SDimitry Andric 
49960b57cec5SDimitry Andric     return !S.RequireCompleteType(
49970b57cec5SDimitry Andric         Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
49980b57cec5SDimitry Andric   }
49990b57cec5SDimitry Andric }
50000b57cec5SDimitry Andric 
HasNoThrowOperator(const RecordType * RT,OverloadedOperatorKind Op,Sema & Self,SourceLocation KeyLoc,ASTContext & C,bool (CXXRecordDecl::* HasTrivial)()const,bool (CXXRecordDecl::* HasNonTrivial)()const,bool (CXXMethodDecl::* IsDesiredOp)()const)50010b57cec5SDimitry Andric static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op,
50020b57cec5SDimitry Andric                                Sema &Self, SourceLocation KeyLoc, ASTContext &C,
50030b57cec5SDimitry Andric                                bool (CXXRecordDecl::*HasTrivial)() const,
50040b57cec5SDimitry Andric                                bool (CXXRecordDecl::*HasNonTrivial)() const,
50050b57cec5SDimitry Andric                                bool (CXXMethodDecl::*IsDesiredOp)() const)
50060b57cec5SDimitry Andric {
50070b57cec5SDimitry Andric   CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
50080b57cec5SDimitry Andric   if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())
50090b57cec5SDimitry Andric     return true;
50100b57cec5SDimitry Andric 
50110b57cec5SDimitry Andric   DeclarationName Name = C.DeclarationNames.getCXXOperatorName(Op);
50120b57cec5SDimitry Andric   DeclarationNameInfo NameInfo(Name, KeyLoc);
50130b57cec5SDimitry Andric   LookupResult Res(Self, NameInfo, Sema::LookupOrdinaryName);
50140b57cec5SDimitry Andric   if (Self.LookupQualifiedName(Res, RD)) {
50150b57cec5SDimitry Andric     bool FoundOperator = false;
50160b57cec5SDimitry Andric     Res.suppressDiagnostics();
50170b57cec5SDimitry Andric     for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end();
50180b57cec5SDimitry Andric          Op != OpEnd; ++Op) {
50190b57cec5SDimitry Andric       if (isa<FunctionTemplateDecl>(*Op))
50200b57cec5SDimitry Andric         continue;
50210b57cec5SDimitry Andric 
50220b57cec5SDimitry Andric       CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);
50230b57cec5SDimitry Andric       if((Operator->*IsDesiredOp)()) {
50240b57cec5SDimitry Andric         FoundOperator = true;
50255ffd83dbSDimitry Andric         auto *CPT = Operator->getType()->castAs<FunctionProtoType>();
50260b57cec5SDimitry Andric         CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
50270b57cec5SDimitry Andric         if (!CPT || !CPT->isNothrow())
50280b57cec5SDimitry Andric           return false;
50290b57cec5SDimitry Andric       }
50300b57cec5SDimitry Andric     }
50310b57cec5SDimitry Andric     return FoundOperator;
50320b57cec5SDimitry Andric   }
50330b57cec5SDimitry Andric   return false;
50340b57cec5SDimitry Andric }
50350b57cec5SDimitry Andric 
EvaluateUnaryTypeTrait(Sema & Self,TypeTrait UTT,SourceLocation KeyLoc,QualType T)50360b57cec5SDimitry Andric static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
50370b57cec5SDimitry Andric                                    SourceLocation KeyLoc, QualType T) {
50380b57cec5SDimitry Andric   assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
50390b57cec5SDimitry Andric 
50400b57cec5SDimitry Andric   ASTContext &C = Self.Context;
50410b57cec5SDimitry Andric   switch(UTT) {
50420b57cec5SDimitry Andric   default: llvm_unreachable("not a UTT");
50430b57cec5SDimitry Andric     // Type trait expressions corresponding to the primary type category
50440b57cec5SDimitry Andric     // predicates in C++0x [meta.unary.cat].
50450b57cec5SDimitry Andric   case UTT_IsVoid:
50460b57cec5SDimitry Andric     return T->isVoidType();
50470b57cec5SDimitry Andric   case UTT_IsIntegral:
50480b57cec5SDimitry Andric     return T->isIntegralType(C);
50490b57cec5SDimitry Andric   case UTT_IsFloatingPoint:
50500b57cec5SDimitry Andric     return T->isFloatingType();
50510b57cec5SDimitry Andric   case UTT_IsArray:
50520b57cec5SDimitry Andric     return T->isArrayType();
5053bdd1243dSDimitry Andric   case UTT_IsBoundedArray:
5054bdd1243dSDimitry Andric     if (!T->isVariableArrayType()) {
5055bdd1243dSDimitry Andric       return T->isArrayType() && !T->isIncompleteArrayType();
5056bdd1243dSDimitry Andric     }
5057bdd1243dSDimitry Andric 
5058bdd1243dSDimitry Andric     Self.Diag(KeyLoc, diag::err_vla_unsupported)
5059bdd1243dSDimitry Andric         << 1 << tok::kw___is_bounded_array;
5060bdd1243dSDimitry Andric     return false;
5061bdd1243dSDimitry Andric   case UTT_IsUnboundedArray:
5062bdd1243dSDimitry Andric     if (!T->isVariableArrayType()) {
5063bdd1243dSDimitry Andric       return T->isIncompleteArrayType();
5064bdd1243dSDimitry Andric     }
5065bdd1243dSDimitry Andric 
5066bdd1243dSDimitry Andric     Self.Diag(KeyLoc, diag::err_vla_unsupported)
5067bdd1243dSDimitry Andric         << 1 << tok::kw___is_unbounded_array;
5068bdd1243dSDimitry Andric     return false;
50690b57cec5SDimitry Andric   case UTT_IsPointer:
50705ffd83dbSDimitry Andric     return T->isAnyPointerType();
5071bdd1243dSDimitry Andric   case UTT_IsNullPointer:
5072bdd1243dSDimitry Andric     return T->isNullPtrType();
50730b57cec5SDimitry Andric   case UTT_IsLvalueReference:
50740b57cec5SDimitry Andric     return T->isLValueReferenceType();
50750b57cec5SDimitry Andric   case UTT_IsRvalueReference:
50760b57cec5SDimitry Andric     return T->isRValueReferenceType();
50770b57cec5SDimitry Andric   case UTT_IsMemberFunctionPointer:
50780b57cec5SDimitry Andric     return T->isMemberFunctionPointerType();
50790b57cec5SDimitry Andric   case UTT_IsMemberObjectPointer:
50800b57cec5SDimitry Andric     return T->isMemberDataPointerType();
50810b57cec5SDimitry Andric   case UTT_IsEnum:
50820b57cec5SDimitry Andric     return T->isEnumeralType();
5083bdd1243dSDimitry Andric   case UTT_IsScopedEnum:
5084bdd1243dSDimitry Andric     return T->isScopedEnumeralType();
50850b57cec5SDimitry Andric   case UTT_IsUnion:
50860b57cec5SDimitry Andric     return T->isUnionType();
50870b57cec5SDimitry Andric   case UTT_IsClass:
50880b57cec5SDimitry Andric     return T->isClassType() || T->isStructureType() || T->isInterfaceType();
50890b57cec5SDimitry Andric   case UTT_IsFunction:
50900b57cec5SDimitry Andric     return T->isFunctionType();
50910b57cec5SDimitry Andric 
50920b57cec5SDimitry Andric     // Type trait expressions which correspond to the convenient composition
50930b57cec5SDimitry Andric     // predicates in C++0x [meta.unary.comp].
50940b57cec5SDimitry Andric   case UTT_IsReference:
50950b57cec5SDimitry Andric     return T->isReferenceType();
50960b57cec5SDimitry Andric   case UTT_IsArithmetic:
50970b57cec5SDimitry Andric     return T->isArithmeticType() && !T->isEnumeralType();
50980b57cec5SDimitry Andric   case UTT_IsFundamental:
50990b57cec5SDimitry Andric     return T->isFundamentalType();
51000b57cec5SDimitry Andric   case UTT_IsObject:
51010b57cec5SDimitry Andric     return T->isObjectType();
51020b57cec5SDimitry Andric   case UTT_IsScalar:
51030b57cec5SDimitry Andric     // Note: semantic analysis depends on Objective-C lifetime types to be
51040b57cec5SDimitry Andric     // considered scalar types. However, such types do not actually behave
51050b57cec5SDimitry Andric     // like scalar types at run time (since they may require retain/release
51060b57cec5SDimitry Andric     // operations), so we report them as non-scalar.
51070b57cec5SDimitry Andric     if (T->isObjCLifetimeType()) {
51080b57cec5SDimitry Andric       switch (T.getObjCLifetime()) {
51090b57cec5SDimitry Andric       case Qualifiers::OCL_None:
51100b57cec5SDimitry Andric       case Qualifiers::OCL_ExplicitNone:
51110b57cec5SDimitry Andric         return true;
51120b57cec5SDimitry Andric 
51130b57cec5SDimitry Andric       case Qualifiers::OCL_Strong:
51140b57cec5SDimitry Andric       case Qualifiers::OCL_Weak:
51150b57cec5SDimitry Andric       case Qualifiers::OCL_Autoreleasing:
51160b57cec5SDimitry Andric         return false;
51170b57cec5SDimitry Andric       }
51180b57cec5SDimitry Andric     }
51190b57cec5SDimitry Andric 
51200b57cec5SDimitry Andric     return T->isScalarType();
51210b57cec5SDimitry Andric   case UTT_IsCompound:
51220b57cec5SDimitry Andric     return T->isCompoundType();
51230b57cec5SDimitry Andric   case UTT_IsMemberPointer:
51240b57cec5SDimitry Andric     return T->isMemberPointerType();
51250b57cec5SDimitry Andric 
51260b57cec5SDimitry Andric     // Type trait expressions which correspond to the type property predicates
51270b57cec5SDimitry Andric     // in C++0x [meta.unary.prop].
51280b57cec5SDimitry Andric   case UTT_IsConst:
51290b57cec5SDimitry Andric     return T.isConstQualified();
51300b57cec5SDimitry Andric   case UTT_IsVolatile:
51310b57cec5SDimitry Andric     return T.isVolatileQualified();
51320b57cec5SDimitry Andric   case UTT_IsTrivial:
51330b57cec5SDimitry Andric     return T.isTrivialType(C);
51340b57cec5SDimitry Andric   case UTT_IsTriviallyCopyable:
51350b57cec5SDimitry Andric     return T.isTriviallyCopyableType(C);
51360b57cec5SDimitry Andric   case UTT_IsStandardLayout:
51370b57cec5SDimitry Andric     return T->isStandardLayoutType();
51380b57cec5SDimitry Andric   case UTT_IsPOD:
51390b57cec5SDimitry Andric     return T.isPODType(C);
51400b57cec5SDimitry Andric   case UTT_IsLiteral:
51410b57cec5SDimitry Andric     return T->isLiteralType(C);
51420b57cec5SDimitry Andric   case UTT_IsEmpty:
51430b57cec5SDimitry Andric     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
51440b57cec5SDimitry Andric       return !RD->isUnion() && RD->isEmpty();
51450b57cec5SDimitry Andric     return false;
51460b57cec5SDimitry Andric   case UTT_IsPolymorphic:
51470b57cec5SDimitry Andric     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
51480b57cec5SDimitry Andric       return !RD->isUnion() && RD->isPolymorphic();
51490b57cec5SDimitry Andric     return false;
51500b57cec5SDimitry Andric   case UTT_IsAbstract:
51510b57cec5SDimitry Andric     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
51520b57cec5SDimitry Andric       return !RD->isUnion() && RD->isAbstract();
51530b57cec5SDimitry Andric     return false;
51540b57cec5SDimitry Andric   case UTT_IsAggregate:
51550b57cec5SDimitry Andric     // Report vector extensions and complex types as aggregates because they
51560b57cec5SDimitry Andric     // support aggregate initialization. GCC mirrors this behavior for vectors
51570b57cec5SDimitry Andric     // but not _Complex.
51580b57cec5SDimitry Andric     return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() ||
51590b57cec5SDimitry Andric            T->isAnyComplexType();
51600b57cec5SDimitry Andric   // __is_interface_class only returns true when CL is invoked in /CLR mode and
51610b57cec5SDimitry Andric   // even then only when it is used with the 'interface struct ...' syntax
51620b57cec5SDimitry Andric   // Clang doesn't support /CLR which makes this type trait moot.
51630b57cec5SDimitry Andric   case UTT_IsInterfaceClass:
51640b57cec5SDimitry Andric     return false;
51650b57cec5SDimitry Andric   case UTT_IsFinal:
51660b57cec5SDimitry Andric   case UTT_IsSealed:
51670b57cec5SDimitry Andric     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
51680b57cec5SDimitry Andric       return RD->hasAttr<FinalAttr>();
51690b57cec5SDimitry Andric     return false;
51700b57cec5SDimitry Andric   case UTT_IsSigned:
5171a7dea167SDimitry Andric     // Enum types should always return false.
5172a7dea167SDimitry Andric     // Floating points should always return true.
5173fe6060f1SDimitry Andric     return T->isFloatingType() ||
5174fe6060f1SDimitry Andric            (T->isSignedIntegerType() && !T->isEnumeralType());
51750b57cec5SDimitry Andric   case UTT_IsUnsigned:
5176fe6060f1SDimitry Andric     // Enum types should always return false.
5177fe6060f1SDimitry Andric     return T->isUnsignedIntegerType() && !T->isEnumeralType();
51780b57cec5SDimitry Andric 
51790b57cec5SDimitry Andric     // Type trait expressions which query classes regarding their construction,
51800b57cec5SDimitry Andric     // destruction, and copying. Rather than being based directly on the
51810b57cec5SDimitry Andric     // related type predicates in the standard, they are specified by both
51820b57cec5SDimitry Andric     // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those
51830b57cec5SDimitry Andric     // specifications.
51840b57cec5SDimitry Andric     //
51850b57cec5SDimitry Andric     //   1: http://gcc.gnu/.org/onlinedocs/gcc/Type-Traits.html
51860b57cec5SDimitry Andric     //   2: http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
51870b57cec5SDimitry Andric     //
51880b57cec5SDimitry Andric     // Note that these builtins do not behave as documented in g++: if a class
51890b57cec5SDimitry Andric     // has both a trivial and a non-trivial special member of a particular kind,
51900b57cec5SDimitry Andric     // they return false! For now, we emulate this behavior.
51910b57cec5SDimitry Andric     // FIXME: This appears to be a g++ bug: more complex cases reveal that it
51920b57cec5SDimitry Andric     // does not correctly compute triviality in the presence of multiple special
51930b57cec5SDimitry Andric     // members of the same kind. Revisit this once the g++ bug is fixed.
51940b57cec5SDimitry Andric   case UTT_HasTrivialDefaultConstructor:
51950b57cec5SDimitry Andric     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
51960b57cec5SDimitry Andric     //   If __is_pod (type) is true then the trait is true, else if type is
51970b57cec5SDimitry Andric     //   a cv class or union type (or array thereof) with a trivial default
51980b57cec5SDimitry Andric     //   constructor ([class.ctor]) then the trait is true, else it is false.
51990b57cec5SDimitry Andric     if (T.isPODType(C))
52000b57cec5SDimitry Andric       return true;
52010b57cec5SDimitry Andric     if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
52020b57cec5SDimitry Andric       return RD->hasTrivialDefaultConstructor() &&
52030b57cec5SDimitry Andric              !RD->hasNonTrivialDefaultConstructor();
52040b57cec5SDimitry Andric     return false;
52050b57cec5SDimitry Andric   case UTT_HasTrivialMoveConstructor:
52060b57cec5SDimitry Andric     //  This trait is implemented by MSVC 2012 and needed to parse the
52070b57cec5SDimitry Andric     //  standard library headers. Specifically this is used as the logic
52080b57cec5SDimitry Andric     //  behind std::is_trivially_move_constructible (20.9.4.3).
52090b57cec5SDimitry Andric     if (T.isPODType(C))
52100b57cec5SDimitry Andric       return true;
52110b57cec5SDimitry Andric     if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
52120b57cec5SDimitry Andric       return RD->hasTrivialMoveConstructor() && !RD->hasNonTrivialMoveConstructor();
52130b57cec5SDimitry Andric     return false;
52140b57cec5SDimitry Andric   case UTT_HasTrivialCopy:
52150b57cec5SDimitry Andric     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
52160b57cec5SDimitry Andric     //   If __is_pod (type) is true or type is a reference type then
52170b57cec5SDimitry Andric     //   the trait is true, else if type is a cv class or union type
52180b57cec5SDimitry Andric     //   with a trivial copy constructor ([class.copy]) then the trait
52190b57cec5SDimitry Andric     //   is true, else it is false.
52200b57cec5SDimitry Andric     if (T.isPODType(C) || T->isReferenceType())
52210b57cec5SDimitry Andric       return true;
52220b57cec5SDimitry Andric     if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
52230b57cec5SDimitry Andric       return RD->hasTrivialCopyConstructor() &&
52240b57cec5SDimitry Andric              !RD->hasNonTrivialCopyConstructor();
52250b57cec5SDimitry Andric     return false;
52260b57cec5SDimitry Andric   case UTT_HasTrivialMoveAssign:
52270b57cec5SDimitry Andric     //  This trait is implemented by MSVC 2012 and needed to parse the
52280b57cec5SDimitry Andric     //  standard library headers. Specifically it is used as the logic
52290b57cec5SDimitry Andric     //  behind std::is_trivially_move_assignable (20.9.4.3)
52300b57cec5SDimitry Andric     if (T.isPODType(C))
52310b57cec5SDimitry Andric       return true;
52320b57cec5SDimitry Andric     if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
52330b57cec5SDimitry Andric       return RD->hasTrivialMoveAssignment() && !RD->hasNonTrivialMoveAssignment();
52340b57cec5SDimitry Andric     return false;
52350b57cec5SDimitry Andric   case UTT_HasTrivialAssign:
52360b57cec5SDimitry Andric     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
52370b57cec5SDimitry Andric     //   If type is const qualified or is a reference type then the
52380b57cec5SDimitry Andric     //   trait is false. Otherwise if __is_pod (type) is true then the
52390b57cec5SDimitry Andric     //   trait is true, else if type is a cv class or union type with
52400b57cec5SDimitry Andric     //   a trivial copy assignment ([class.copy]) then the trait is
52410b57cec5SDimitry Andric     //   true, else it is false.
52420b57cec5SDimitry Andric     // Note: the const and reference restrictions are interesting,
52430b57cec5SDimitry Andric     // given that const and reference members don't prevent a class
52440b57cec5SDimitry Andric     // from having a trivial copy assignment operator (but do cause
52450b57cec5SDimitry Andric     // errors if the copy assignment operator is actually used, q.v.
52460b57cec5SDimitry Andric     // [class.copy]p12).
52470b57cec5SDimitry Andric 
52480b57cec5SDimitry Andric     if (T.isConstQualified())
52490b57cec5SDimitry Andric       return false;
52500b57cec5SDimitry Andric     if (T.isPODType(C))
52510b57cec5SDimitry Andric       return true;
52520b57cec5SDimitry Andric     if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
52530b57cec5SDimitry Andric       return RD->hasTrivialCopyAssignment() &&
52540b57cec5SDimitry Andric              !RD->hasNonTrivialCopyAssignment();
52550b57cec5SDimitry Andric     return false;
52560b57cec5SDimitry Andric   case UTT_IsDestructible:
52570b57cec5SDimitry Andric   case UTT_IsTriviallyDestructible:
52580b57cec5SDimitry Andric   case UTT_IsNothrowDestructible:
52590b57cec5SDimitry Andric     // C++14 [meta.unary.prop]:
52600b57cec5SDimitry Andric     //   For reference types, is_destructible<T>::value is true.
52610b57cec5SDimitry Andric     if (T->isReferenceType())
52620b57cec5SDimitry Andric       return true;
52630b57cec5SDimitry Andric 
52640b57cec5SDimitry Andric     // Objective-C++ ARC: autorelease types don't require destruction.
52650b57cec5SDimitry Andric     if (T->isObjCLifetimeType() &&
52660b57cec5SDimitry Andric         T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
52670b57cec5SDimitry Andric       return true;
52680b57cec5SDimitry Andric 
52690b57cec5SDimitry Andric     // C++14 [meta.unary.prop]:
52700b57cec5SDimitry Andric     //   For incomplete types and function types, is_destructible<T>::value is
52710b57cec5SDimitry Andric     //   false.
52720b57cec5SDimitry Andric     if (T->isIncompleteType() || T->isFunctionType())
52730b57cec5SDimitry Andric       return false;
52740b57cec5SDimitry Andric 
52750b57cec5SDimitry Andric     // A type that requires destruction (via a non-trivial destructor or ARC
52760b57cec5SDimitry Andric     // lifetime semantics) is not trivially-destructible.
52770b57cec5SDimitry Andric     if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())
52780b57cec5SDimitry Andric       return false;
52790b57cec5SDimitry Andric 
52800b57cec5SDimitry Andric     // C++14 [meta.unary.prop]:
52810b57cec5SDimitry Andric     //   For object types and given U equal to remove_all_extents_t<T>, if the
52820b57cec5SDimitry Andric     //   expression std::declval<U&>().~U() is well-formed when treated as an
52830b57cec5SDimitry Andric     //   unevaluated operand (Clause 5), then is_destructible<T>::value is true
52840b57cec5SDimitry Andric     if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
52850b57cec5SDimitry Andric       CXXDestructorDecl *Destructor = Self.LookupDestructor(RD);
52860b57cec5SDimitry Andric       if (!Destructor)
52870b57cec5SDimitry Andric         return false;
52880b57cec5SDimitry Andric       //  C++14 [dcl.fct.def.delete]p2:
52890b57cec5SDimitry Andric       //    A program that refers to a deleted function implicitly or
52900b57cec5SDimitry Andric       //    explicitly, other than to declare it, is ill-formed.
52910b57cec5SDimitry Andric       if (Destructor->isDeleted())
52920b57cec5SDimitry Andric         return false;
52930b57cec5SDimitry Andric       if (C.getLangOpts().AccessControl && Destructor->getAccess() != AS_public)
52940b57cec5SDimitry Andric         return false;
52950b57cec5SDimitry Andric       if (UTT == UTT_IsNothrowDestructible) {
52965ffd83dbSDimitry Andric         auto *CPT = Destructor->getType()->castAs<FunctionProtoType>();
52970b57cec5SDimitry Andric         CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
52980b57cec5SDimitry Andric         if (!CPT || !CPT->isNothrow())
52990b57cec5SDimitry Andric           return false;
53000b57cec5SDimitry Andric       }
53010b57cec5SDimitry Andric     }
53020b57cec5SDimitry Andric     return true;
53030b57cec5SDimitry Andric 
53040b57cec5SDimitry Andric   case UTT_HasTrivialDestructor:
53050b57cec5SDimitry Andric     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
53060b57cec5SDimitry Andric     //   If __is_pod (type) is true or type is a reference type
53070b57cec5SDimitry Andric     //   then the trait is true, else if type is a cv class or union
53080b57cec5SDimitry Andric     //   type (or array thereof) with a trivial destructor
53090b57cec5SDimitry Andric     //   ([class.dtor]) then the trait is true, else it is
53100b57cec5SDimitry Andric     //   false.
53110b57cec5SDimitry Andric     if (T.isPODType(C) || T->isReferenceType())
53120b57cec5SDimitry Andric       return true;
53130b57cec5SDimitry Andric 
53140b57cec5SDimitry Andric     // Objective-C++ ARC: autorelease types don't require destruction.
53150b57cec5SDimitry Andric     if (T->isObjCLifetimeType() &&
53160b57cec5SDimitry Andric         T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
53170b57cec5SDimitry Andric       return true;
53180b57cec5SDimitry Andric 
53190b57cec5SDimitry Andric     if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
53200b57cec5SDimitry Andric       return RD->hasTrivialDestructor();
53210b57cec5SDimitry Andric     return false;
53220b57cec5SDimitry Andric   // TODO: Propagate nothrowness for implicitly declared special members.
53230b57cec5SDimitry Andric   case UTT_HasNothrowAssign:
53240b57cec5SDimitry Andric     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
53250b57cec5SDimitry Andric     //   If type is const qualified or is a reference type then the
53260b57cec5SDimitry Andric     //   trait is false. Otherwise if __has_trivial_assign (type)
53270b57cec5SDimitry Andric     //   is true then the trait is true, else if type is a cv class
53280b57cec5SDimitry Andric     //   or union type with copy assignment operators that are known
53290b57cec5SDimitry Andric     //   not to throw an exception then the trait is true, else it is
53300b57cec5SDimitry Andric     //   false.
53310b57cec5SDimitry Andric     if (C.getBaseElementType(T).isConstQualified())
53320b57cec5SDimitry Andric       return false;
53330b57cec5SDimitry Andric     if (T->isReferenceType())
53340b57cec5SDimitry Andric       return false;
53350b57cec5SDimitry Andric     if (T.isPODType(C) || T->isObjCLifetimeType())
53360b57cec5SDimitry Andric       return true;
53370b57cec5SDimitry Andric 
53380b57cec5SDimitry Andric     if (const RecordType *RT = T->getAs<RecordType>())
53390b57cec5SDimitry Andric       return HasNoThrowOperator(RT, OO_Equal, Self, KeyLoc, C,
53400b57cec5SDimitry Andric                                 &CXXRecordDecl::hasTrivialCopyAssignment,
53410b57cec5SDimitry Andric                                 &CXXRecordDecl::hasNonTrivialCopyAssignment,
53420b57cec5SDimitry Andric                                 &CXXMethodDecl::isCopyAssignmentOperator);
53430b57cec5SDimitry Andric     return false;
53440b57cec5SDimitry Andric   case UTT_HasNothrowMoveAssign:
53450b57cec5SDimitry Andric     //  This trait is implemented by MSVC 2012 and needed to parse the
53460b57cec5SDimitry Andric     //  standard library headers. Specifically this is used as the logic
53470b57cec5SDimitry Andric     //  behind std::is_nothrow_move_assignable (20.9.4.3).
53480b57cec5SDimitry Andric     if (T.isPODType(C))
53490b57cec5SDimitry Andric       return true;
53500b57cec5SDimitry Andric 
53510b57cec5SDimitry Andric     if (const RecordType *RT = C.getBaseElementType(T)->getAs<RecordType>())
53520b57cec5SDimitry Andric       return HasNoThrowOperator(RT, OO_Equal, Self, KeyLoc, C,
53530b57cec5SDimitry Andric                                 &CXXRecordDecl::hasTrivialMoveAssignment,
53540b57cec5SDimitry Andric                                 &CXXRecordDecl::hasNonTrivialMoveAssignment,
53550b57cec5SDimitry Andric                                 &CXXMethodDecl::isMoveAssignmentOperator);
53560b57cec5SDimitry Andric     return false;
53570b57cec5SDimitry Andric   case UTT_HasNothrowCopy:
53580b57cec5SDimitry Andric     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
53590b57cec5SDimitry Andric     //   If __has_trivial_copy (type) is true then the trait is true, else
53600b57cec5SDimitry Andric     //   if type is a cv class or union type with copy constructors that are
53610b57cec5SDimitry Andric     //   known not to throw an exception then the trait is true, else it is
53620b57cec5SDimitry Andric     //   false.
53630b57cec5SDimitry Andric     if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType())
53640b57cec5SDimitry Andric       return true;
53650b57cec5SDimitry Andric     if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
53660b57cec5SDimitry Andric       if (RD->hasTrivialCopyConstructor() &&
53670b57cec5SDimitry Andric           !RD->hasNonTrivialCopyConstructor())
53680b57cec5SDimitry Andric         return true;
53690b57cec5SDimitry Andric 
53700b57cec5SDimitry Andric       bool FoundConstructor = false;
53710b57cec5SDimitry Andric       unsigned FoundTQs;
53720b57cec5SDimitry Andric       for (const auto *ND : Self.LookupConstructors(RD)) {
53730b57cec5SDimitry Andric         // A template constructor is never a copy constructor.
53740b57cec5SDimitry Andric         // FIXME: However, it may actually be selected at the actual overload
53750b57cec5SDimitry Andric         // resolution point.
53760b57cec5SDimitry Andric         if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
53770b57cec5SDimitry Andric           continue;
53780b57cec5SDimitry Andric         // UsingDecl itself is not a constructor
53790b57cec5SDimitry Andric         if (isa<UsingDecl>(ND))
53800b57cec5SDimitry Andric           continue;
53810b57cec5SDimitry Andric         auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
53820b57cec5SDimitry Andric         if (Constructor->isCopyConstructor(FoundTQs)) {
53830b57cec5SDimitry Andric           FoundConstructor = true;
53845ffd83dbSDimitry Andric           auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
53850b57cec5SDimitry Andric           CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
53860b57cec5SDimitry Andric           if (!CPT)
53870b57cec5SDimitry Andric             return false;
53880b57cec5SDimitry Andric           // TODO: check whether evaluating default arguments can throw.
53890b57cec5SDimitry Andric           // For now, we'll be conservative and assume that they can throw.
53900b57cec5SDimitry Andric           if (!CPT->isNothrow() || CPT->getNumParams() > 1)
53910b57cec5SDimitry Andric             return false;
53920b57cec5SDimitry Andric         }
53930b57cec5SDimitry Andric       }
53940b57cec5SDimitry Andric 
53950b57cec5SDimitry Andric       return FoundConstructor;
53960b57cec5SDimitry Andric     }
53970b57cec5SDimitry Andric     return false;
53980b57cec5SDimitry Andric   case UTT_HasNothrowConstructor:
53990b57cec5SDimitry Andric     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
54000b57cec5SDimitry Andric     //   If __has_trivial_constructor (type) is true then the trait is
54010b57cec5SDimitry Andric     //   true, else if type is a cv class or union type (or array
54020b57cec5SDimitry Andric     //   thereof) with a default constructor that is known not to
54030b57cec5SDimitry Andric     //   throw an exception then the trait is true, else it is false.
54040b57cec5SDimitry Andric     if (T.isPODType(C) || T->isObjCLifetimeType())
54050b57cec5SDimitry Andric       return true;
54060b57cec5SDimitry Andric     if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
54070b57cec5SDimitry Andric       if (RD->hasTrivialDefaultConstructor() &&
54080b57cec5SDimitry Andric           !RD->hasNonTrivialDefaultConstructor())
54090b57cec5SDimitry Andric         return true;
54100b57cec5SDimitry Andric 
54110b57cec5SDimitry Andric       bool FoundConstructor = false;
54120b57cec5SDimitry Andric       for (const auto *ND : Self.LookupConstructors(RD)) {
54130b57cec5SDimitry Andric         // FIXME: In C++0x, a constructor template can be a default constructor.
54140b57cec5SDimitry Andric         if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
54150b57cec5SDimitry Andric           continue;
54160b57cec5SDimitry Andric         // UsingDecl itself is not a constructor
54170b57cec5SDimitry Andric         if (isa<UsingDecl>(ND))
54180b57cec5SDimitry Andric           continue;
54190b57cec5SDimitry Andric         auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
54200b57cec5SDimitry Andric         if (Constructor->isDefaultConstructor()) {
54210b57cec5SDimitry Andric           FoundConstructor = true;
54225ffd83dbSDimitry Andric           auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
54230b57cec5SDimitry Andric           CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
54240b57cec5SDimitry Andric           if (!CPT)
54250b57cec5SDimitry Andric             return false;
54260b57cec5SDimitry Andric           // FIXME: check whether evaluating default arguments can throw.
54270b57cec5SDimitry Andric           // For now, we'll be conservative and assume that they can throw.
54280b57cec5SDimitry Andric           if (!CPT->isNothrow() || CPT->getNumParams() > 0)
54290b57cec5SDimitry Andric             return false;
54300b57cec5SDimitry Andric         }
54310b57cec5SDimitry Andric       }
54320b57cec5SDimitry Andric       return FoundConstructor;
54330b57cec5SDimitry Andric     }
54340b57cec5SDimitry Andric     return false;
54350b57cec5SDimitry Andric   case UTT_HasVirtualDestructor:
54360b57cec5SDimitry Andric     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
54370b57cec5SDimitry Andric     //   If type is a class type with a virtual destructor ([class.dtor])
54380b57cec5SDimitry Andric     //   then the trait is true, else it is false.
54390b57cec5SDimitry Andric     if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
54400b57cec5SDimitry Andric       if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD))
54410b57cec5SDimitry Andric         return Destructor->isVirtual();
54420b57cec5SDimitry Andric     return false;
54430b57cec5SDimitry Andric 
54440b57cec5SDimitry Andric     // These type trait expressions are modeled on the specifications for the
54450b57cec5SDimitry Andric     // Embarcadero C++0x type trait functions:
54460b57cec5SDimitry Andric     //   http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
54470b57cec5SDimitry Andric   case UTT_IsCompleteType:
54480b57cec5SDimitry Andric     // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_):
54490b57cec5SDimitry Andric     //   Returns True if and only if T is a complete type at the point of the
54500b57cec5SDimitry Andric     //   function call.
54510b57cec5SDimitry Andric     return !T->isIncompleteType();
54520b57cec5SDimitry Andric   case UTT_HasUniqueObjectRepresentations:
54530b57cec5SDimitry Andric     return C.hasUniqueObjectRepresentations(T);
545481ad6265SDimitry Andric   case UTT_IsTriviallyRelocatable:
545581ad6265SDimitry Andric     return T.isTriviallyRelocatableType(C);
5456bdd1243dSDimitry Andric   case UTT_IsReferenceable:
5457bdd1243dSDimitry Andric     return T.isReferenceable();
545806c3fb27SDimitry Andric   case UTT_CanPassInRegs:
545906c3fb27SDimitry Andric     if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers())
546006c3fb27SDimitry Andric       return RD->canPassInRegisters();
546106c3fb27SDimitry Andric     Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) << T;
546206c3fb27SDimitry Andric     return false;
546306c3fb27SDimitry Andric   case UTT_IsTriviallyEqualityComparable:
546406c3fb27SDimitry Andric     return T.isTriviallyEqualityComparableType(C);
54650b57cec5SDimitry Andric   }
54660b57cec5SDimitry Andric }
54670b57cec5SDimitry Andric 
54680b57cec5SDimitry Andric static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
54690b57cec5SDimitry Andric                                     QualType RhsT, SourceLocation KeyLoc);
54700b57cec5SDimitry Andric 
EvaluateBooleanTypeTrait(Sema & S,TypeTrait Kind,SourceLocation KWLoc,ArrayRef<TypeSourceInfo * > Args,SourceLocation RParenLoc,bool IsDependent)547106c3fb27SDimitry Andric static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind,
547206c3fb27SDimitry Andric                                      SourceLocation KWLoc,
54730b57cec5SDimitry Andric                                      ArrayRef<TypeSourceInfo *> Args,
547406c3fb27SDimitry Andric                                      SourceLocation RParenLoc,
547506c3fb27SDimitry Andric                                      bool IsDependent) {
547606c3fb27SDimitry Andric   if (IsDependent)
547706c3fb27SDimitry Andric     return false;
547806c3fb27SDimitry Andric 
54790b57cec5SDimitry Andric   if (Kind <= UTT_Last)
54800b57cec5SDimitry Andric     return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]->getType());
54810b57cec5SDimitry Andric 
54825f757f3fSDimitry Andric   // Evaluate ReferenceBindsToTemporary and ReferenceConstructsFromTemporary
54835f757f3fSDimitry Andric   // alongside the IsConstructible traits to avoid duplication.
54845f757f3fSDimitry Andric   if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary && Kind != BTT_ReferenceConstructsFromTemporary)
54850b57cec5SDimitry Andric     return EvaluateBinaryTypeTrait(S, Kind, Args[0]->getType(),
54860b57cec5SDimitry Andric                                    Args[1]->getType(), RParenLoc);
54870b57cec5SDimitry Andric 
54880b57cec5SDimitry Andric   switch (Kind) {
54890b57cec5SDimitry Andric   case clang::BTT_ReferenceBindsToTemporary:
54905f757f3fSDimitry Andric   case clang::BTT_ReferenceConstructsFromTemporary:
54910b57cec5SDimitry Andric   case clang::TT_IsConstructible:
54920b57cec5SDimitry Andric   case clang::TT_IsNothrowConstructible:
54930b57cec5SDimitry Andric   case clang::TT_IsTriviallyConstructible: {
54940b57cec5SDimitry Andric     // C++11 [meta.unary.prop]:
54950b57cec5SDimitry Andric     //   is_trivially_constructible is defined as:
54960b57cec5SDimitry Andric     //
54970b57cec5SDimitry Andric     //     is_constructible<T, Args...>::value is true and the variable
54980b57cec5SDimitry Andric     //     definition for is_constructible, as defined below, is known to call
54990b57cec5SDimitry Andric     //     no operation that is not trivial.
55000b57cec5SDimitry Andric     //
55010b57cec5SDimitry Andric     //   The predicate condition for a template specialization
55020b57cec5SDimitry Andric     //   is_constructible<T, Args...> shall be satisfied if and only if the
55030b57cec5SDimitry Andric     //   following variable definition would be well-formed for some invented
55040b57cec5SDimitry Andric     //   variable t:
55050b57cec5SDimitry Andric     //
55060b57cec5SDimitry Andric     //     T t(create<Args>()...);
55070b57cec5SDimitry Andric     assert(!Args.empty());
55080b57cec5SDimitry Andric 
55090b57cec5SDimitry Andric     // Precondition: T and all types in the parameter pack Args shall be
55100b57cec5SDimitry Andric     // complete types, (possibly cv-qualified) void, or arrays of
55110b57cec5SDimitry Andric     // unknown bound.
55120b57cec5SDimitry Andric     for (const auto *TSI : Args) {
55130b57cec5SDimitry Andric       QualType ArgTy = TSI->getType();
55140b57cec5SDimitry Andric       if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
55150b57cec5SDimitry Andric         continue;
55160b57cec5SDimitry Andric 
55170b57cec5SDimitry Andric       if (S.RequireCompleteType(KWLoc, ArgTy,
55180b57cec5SDimitry Andric           diag::err_incomplete_type_used_in_type_trait_expr))
55190b57cec5SDimitry Andric         return false;
55200b57cec5SDimitry Andric     }
55210b57cec5SDimitry Andric 
55220b57cec5SDimitry Andric     // Make sure the first argument is not incomplete nor a function type.
55230b57cec5SDimitry Andric     QualType T = Args[0]->getType();
55240b57cec5SDimitry Andric     if (T->isIncompleteType() || T->isFunctionType())
55250b57cec5SDimitry Andric       return false;
55260b57cec5SDimitry Andric 
55270b57cec5SDimitry Andric     // Make sure the first argument is not an abstract type.
55280b57cec5SDimitry Andric     CXXRecordDecl *RD = T->getAsCXXRecordDecl();
55290b57cec5SDimitry Andric     if (RD && RD->isAbstract())
55300b57cec5SDimitry Andric       return false;
55310b57cec5SDimitry Andric 
55325ffd83dbSDimitry Andric     llvm::BumpPtrAllocator OpaqueExprAllocator;
55330b57cec5SDimitry Andric     SmallVector<Expr *, 2> ArgExprs;
55340b57cec5SDimitry Andric     ArgExprs.reserve(Args.size() - 1);
55350b57cec5SDimitry Andric     for (unsigned I = 1, N = Args.size(); I != N; ++I) {
55360b57cec5SDimitry Andric       QualType ArgTy = Args[I]->getType();
55370b57cec5SDimitry Andric       if (ArgTy->isObjectType() || ArgTy->isFunctionType())
55380b57cec5SDimitry Andric         ArgTy = S.Context.getRValueReferenceType(ArgTy);
55395ffd83dbSDimitry Andric       ArgExprs.push_back(
55405ffd83dbSDimitry Andric           new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
55410b57cec5SDimitry Andric               OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),
55420b57cec5SDimitry Andric                               ArgTy.getNonLValueExprType(S.Context),
55430b57cec5SDimitry Andric                               Expr::getValueKindForType(ArgTy)));
55440b57cec5SDimitry Andric     }
55450b57cec5SDimitry Andric 
55460b57cec5SDimitry Andric     // Perform the initialization in an unevaluated context within a SFINAE
55470b57cec5SDimitry Andric     // trap at translation unit scope.
55480b57cec5SDimitry Andric     EnterExpressionEvaluationContext Unevaluated(
55490b57cec5SDimitry Andric         S, Sema::ExpressionEvaluationContext::Unevaluated);
55500b57cec5SDimitry Andric     Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true);
55510b57cec5SDimitry Andric     Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
5552349cc55cSDimitry Andric     InitializedEntity To(
5553349cc55cSDimitry Andric         InitializedEntity::InitializeTemporary(S.Context, Args[0]));
55540b57cec5SDimitry Andric     InitializationKind InitKind(InitializationKind::CreateDirect(KWLoc, KWLoc,
55550b57cec5SDimitry Andric                                                                  RParenLoc));
55560b57cec5SDimitry Andric     InitializationSequence Init(S, To, InitKind, ArgExprs);
55570b57cec5SDimitry Andric     if (Init.Failed())
55580b57cec5SDimitry Andric       return false;
55590b57cec5SDimitry Andric 
55600b57cec5SDimitry Andric     ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
55610b57cec5SDimitry Andric     if (Result.isInvalid() || SFINAE.hasErrorOccurred())
55620b57cec5SDimitry Andric       return false;
55630b57cec5SDimitry Andric 
55640b57cec5SDimitry Andric     if (Kind == clang::TT_IsConstructible)
55650b57cec5SDimitry Andric       return true;
55660b57cec5SDimitry Andric 
55675f757f3fSDimitry Andric     if (Kind == clang::BTT_ReferenceBindsToTemporary || Kind == clang::BTT_ReferenceConstructsFromTemporary) {
55680b57cec5SDimitry Andric       if (!T->isReferenceType())
55690b57cec5SDimitry Andric         return false;
55700b57cec5SDimitry Andric 
55715f757f3fSDimitry Andric       if (!Init.isDirectReferenceBinding())
55725f757f3fSDimitry Andric         return true;
55735f757f3fSDimitry Andric 
55745f757f3fSDimitry Andric       if (Kind == clang::BTT_ReferenceBindsToTemporary)
55755f757f3fSDimitry Andric         return false;
55765f757f3fSDimitry Andric 
55775f757f3fSDimitry Andric       QualType U = Args[1]->getType();
55785f757f3fSDimitry Andric       if (U->isReferenceType())
55795f757f3fSDimitry Andric         return false;
55805f757f3fSDimitry Andric 
55815f757f3fSDimitry Andric       QualType TPtr = S.Context.getPointerType(S.BuiltinRemoveReference(T, UnaryTransformType::RemoveCVRef, {}));
55825f757f3fSDimitry Andric       QualType UPtr = S.Context.getPointerType(S.BuiltinRemoveReference(U, UnaryTransformType::RemoveCVRef, {}));
55835f757f3fSDimitry Andric       return EvaluateBinaryTypeTrait(S, TypeTrait::BTT_IsConvertibleTo, UPtr, TPtr, RParenLoc);
55840b57cec5SDimitry Andric     }
55850b57cec5SDimitry Andric 
55860b57cec5SDimitry Andric     if (Kind == clang::TT_IsNothrowConstructible)
55870b57cec5SDimitry Andric       return S.canThrow(Result.get()) == CT_Cannot;
55880b57cec5SDimitry Andric 
55890b57cec5SDimitry Andric     if (Kind == clang::TT_IsTriviallyConstructible) {
55900b57cec5SDimitry Andric       // Under Objective-C ARC and Weak, if the destination has non-trivial
55910b57cec5SDimitry Andric       // Objective-C lifetime, this is a non-trivial construction.
55920b57cec5SDimitry Andric       if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
55930b57cec5SDimitry Andric         return false;
55940b57cec5SDimitry Andric 
55950b57cec5SDimitry Andric       // The initialization succeeded; now make sure there are no non-trivial
55960b57cec5SDimitry Andric       // calls.
55970b57cec5SDimitry Andric       return !Result.get()->hasNonTrivialCall(S.Context);
55980b57cec5SDimitry Andric     }
55990b57cec5SDimitry Andric 
56000b57cec5SDimitry Andric     llvm_unreachable("unhandled type trait");
56010b57cec5SDimitry Andric     return false;
56020b57cec5SDimitry Andric   }
56030b57cec5SDimitry Andric     default: llvm_unreachable("not a TT");
56040b57cec5SDimitry Andric   }
56050b57cec5SDimitry Andric 
56060b57cec5SDimitry Andric   return false;
56070b57cec5SDimitry Andric }
56080b57cec5SDimitry Andric 
5609753f127fSDimitry Andric namespace {
DiagnoseBuiltinDeprecation(Sema & S,TypeTrait Kind,SourceLocation KWLoc)5610753f127fSDimitry Andric void DiagnoseBuiltinDeprecation(Sema& S, TypeTrait Kind,
5611753f127fSDimitry Andric                                 SourceLocation KWLoc) {
5612753f127fSDimitry Andric   TypeTrait Replacement;
5613753f127fSDimitry Andric   switch (Kind) {
5614753f127fSDimitry Andric     case UTT_HasNothrowAssign:
5615753f127fSDimitry Andric     case UTT_HasNothrowMoveAssign:
5616753f127fSDimitry Andric       Replacement = BTT_IsNothrowAssignable;
5617753f127fSDimitry Andric       break;
5618753f127fSDimitry Andric     case UTT_HasNothrowCopy:
5619753f127fSDimitry Andric     case UTT_HasNothrowConstructor:
5620753f127fSDimitry Andric       Replacement = TT_IsNothrowConstructible;
5621753f127fSDimitry Andric       break;
5622753f127fSDimitry Andric     case UTT_HasTrivialAssign:
5623753f127fSDimitry Andric     case UTT_HasTrivialMoveAssign:
5624753f127fSDimitry Andric       Replacement = BTT_IsTriviallyAssignable;
5625753f127fSDimitry Andric       break;
5626753f127fSDimitry Andric     case UTT_HasTrivialCopy:
5627a4a491e2SDimitry Andric       Replacement = UTT_IsTriviallyCopyable;
5628a4a491e2SDimitry Andric       break;
5629753f127fSDimitry Andric     case UTT_HasTrivialDefaultConstructor:
5630753f127fSDimitry Andric     case UTT_HasTrivialMoveConstructor:
5631753f127fSDimitry Andric       Replacement = TT_IsTriviallyConstructible;
5632753f127fSDimitry Andric       break;
5633753f127fSDimitry Andric     case UTT_HasTrivialDestructor:
5634753f127fSDimitry Andric       Replacement = UTT_IsTriviallyDestructible;
5635753f127fSDimitry Andric       break;
5636753f127fSDimitry Andric     default:
5637753f127fSDimitry Andric       return;
5638753f127fSDimitry Andric   }
5639753f127fSDimitry Andric   S.Diag(KWLoc, diag::warn_deprecated_builtin)
5640753f127fSDimitry Andric     << getTraitSpelling(Kind) << getTraitSpelling(Replacement);
5641753f127fSDimitry Andric }
5642753f127fSDimitry Andric }
5643753f127fSDimitry Andric 
CheckTypeTraitArity(unsigned Arity,SourceLocation Loc,size_t N)5644bdd1243dSDimitry Andric bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {
5645bdd1243dSDimitry Andric   if (Arity && N != Arity) {
5646bdd1243dSDimitry Andric     Diag(Loc, diag::err_type_trait_arity)
5647bdd1243dSDimitry Andric         << Arity << 0 << (Arity > 1) << (int)N << SourceRange(Loc);
5648bdd1243dSDimitry Andric     return false;
5649bdd1243dSDimitry Andric   }
5650bdd1243dSDimitry Andric 
5651bdd1243dSDimitry Andric   if (!Arity && N == 0) {
5652bdd1243dSDimitry Andric     Diag(Loc, diag::err_type_trait_arity)
5653bdd1243dSDimitry Andric         << 1 << 1 << 1 << (int)N << SourceRange(Loc);
5654bdd1243dSDimitry Andric     return false;
5655bdd1243dSDimitry Andric   }
5656bdd1243dSDimitry Andric   return true;
5657bdd1243dSDimitry Andric }
5658bdd1243dSDimitry Andric 
565906c3fb27SDimitry Andric enum class TypeTraitReturnType {
566006c3fb27SDimitry Andric   Bool,
566106c3fb27SDimitry Andric };
566206c3fb27SDimitry Andric 
GetReturnType(TypeTrait Kind)566306c3fb27SDimitry Andric static TypeTraitReturnType GetReturnType(TypeTrait Kind) {
566406c3fb27SDimitry Andric   return TypeTraitReturnType::Bool;
566506c3fb27SDimitry Andric }
566606c3fb27SDimitry Andric 
BuildTypeTrait(TypeTrait Kind,SourceLocation KWLoc,ArrayRef<TypeSourceInfo * > Args,SourceLocation RParenLoc)56670b57cec5SDimitry Andric ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
56680b57cec5SDimitry Andric                                 ArrayRef<TypeSourceInfo *> Args,
56690b57cec5SDimitry Andric                                 SourceLocation RParenLoc) {
5670bdd1243dSDimitry Andric   if (!CheckTypeTraitArity(getTypeTraitArity(Kind), KWLoc, Args.size()))
5671bdd1243dSDimitry Andric     return ExprError();
56720b57cec5SDimitry Andric 
56730b57cec5SDimitry Andric   if (Kind <= UTT_Last && !CheckUnaryTypeTraitTypeCompleteness(
56740b57cec5SDimitry Andric                                *this, Kind, KWLoc, Args[0]->getType()))
56750b57cec5SDimitry Andric     return ExprError();
56760b57cec5SDimitry Andric 
5677753f127fSDimitry Andric   DiagnoseBuiltinDeprecation(*this, Kind, KWLoc);
5678753f127fSDimitry Andric 
56790b57cec5SDimitry Andric   bool Dependent = false;
56800b57cec5SDimitry Andric   for (unsigned I = 0, N = Args.size(); I != N; ++I) {
56810b57cec5SDimitry Andric     if (Args[I]->getType()->isDependentType()) {
56820b57cec5SDimitry Andric       Dependent = true;
56830b57cec5SDimitry Andric       break;
56840b57cec5SDimitry Andric     }
56850b57cec5SDimitry Andric   }
56860b57cec5SDimitry Andric 
568706c3fb27SDimitry Andric   switch (GetReturnType(Kind)) {
568806c3fb27SDimitry Andric   case TypeTraitReturnType::Bool: {
568906c3fb27SDimitry Andric     bool Result = EvaluateBooleanTypeTrait(*this, Kind, KWLoc, Args, RParenLoc,
569006c3fb27SDimitry Andric                                            Dependent);
569106c3fb27SDimitry Andric     return TypeTraitExpr::Create(Context, Context.getLogicalOperationType(),
569206c3fb27SDimitry Andric                                  KWLoc, Kind, Args, RParenLoc, Result);
569306c3fb27SDimitry Andric   }
569406c3fb27SDimitry Andric   }
569506c3fb27SDimitry Andric   llvm_unreachable("unhandled type trait return type");
56960b57cec5SDimitry Andric }
56970b57cec5SDimitry Andric 
ActOnTypeTrait(TypeTrait Kind,SourceLocation KWLoc,ArrayRef<ParsedType> Args,SourceLocation RParenLoc)56980b57cec5SDimitry Andric ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
56990b57cec5SDimitry Andric                                 ArrayRef<ParsedType> Args,
57000b57cec5SDimitry Andric                                 SourceLocation RParenLoc) {
57010b57cec5SDimitry Andric   SmallVector<TypeSourceInfo *, 4> ConvertedArgs;
57020b57cec5SDimitry Andric   ConvertedArgs.reserve(Args.size());
57030b57cec5SDimitry Andric 
57040b57cec5SDimitry Andric   for (unsigned I = 0, N = Args.size(); I != N; ++I) {
57050b57cec5SDimitry Andric     TypeSourceInfo *TInfo;
57060b57cec5SDimitry Andric     QualType T = GetTypeFromParser(Args[I], &TInfo);
57070b57cec5SDimitry Andric     if (!TInfo)
57080b57cec5SDimitry Andric       TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);
57090b57cec5SDimitry Andric 
57100b57cec5SDimitry Andric     ConvertedArgs.push_back(TInfo);
57110b57cec5SDimitry Andric   }
57120b57cec5SDimitry Andric 
57130b57cec5SDimitry Andric   return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
57140b57cec5SDimitry Andric }
57150b57cec5SDimitry Andric 
EvaluateBinaryTypeTrait(Sema & Self,TypeTrait BTT,QualType LhsT,QualType RhsT,SourceLocation KeyLoc)57160b57cec5SDimitry Andric static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
57170b57cec5SDimitry Andric                                     QualType RhsT, SourceLocation KeyLoc) {
57180b57cec5SDimitry Andric   assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
57190b57cec5SDimitry Andric          "Cannot evaluate traits of dependent types");
57200b57cec5SDimitry Andric 
57210b57cec5SDimitry Andric   switch(BTT) {
57220b57cec5SDimitry Andric   case BTT_IsBaseOf: {
57230b57cec5SDimitry Andric     // C++0x [meta.rel]p2
57240b57cec5SDimitry Andric     // Base is a base class of Derived without regard to cv-qualifiers or
57250b57cec5SDimitry Andric     // Base and Derived are not unions and name the same class type without
57260b57cec5SDimitry Andric     // regard to cv-qualifiers.
57270b57cec5SDimitry Andric 
57280b57cec5SDimitry Andric     const RecordType *lhsRecord = LhsT->getAs<RecordType>();
57290b57cec5SDimitry Andric     const RecordType *rhsRecord = RhsT->getAs<RecordType>();
57300b57cec5SDimitry Andric     if (!rhsRecord || !lhsRecord) {
57310b57cec5SDimitry Andric       const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();
57320b57cec5SDimitry Andric       const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();
57330b57cec5SDimitry Andric       if (!LHSObjTy || !RHSObjTy)
57340b57cec5SDimitry Andric         return false;
57350b57cec5SDimitry Andric 
57360b57cec5SDimitry Andric       ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
57370b57cec5SDimitry Andric       ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
57380b57cec5SDimitry Andric       if (!BaseInterface || !DerivedInterface)
57390b57cec5SDimitry Andric         return false;
57400b57cec5SDimitry Andric 
57410b57cec5SDimitry Andric       if (Self.RequireCompleteType(
57420b57cec5SDimitry Andric               KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr))
57430b57cec5SDimitry Andric         return false;
57440b57cec5SDimitry Andric 
57450b57cec5SDimitry Andric       return BaseInterface->isSuperClassOf(DerivedInterface);
57460b57cec5SDimitry Andric     }
57470b57cec5SDimitry Andric 
57480b57cec5SDimitry Andric     assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT)
57490b57cec5SDimitry Andric              == (lhsRecord == rhsRecord));
57500b57cec5SDimitry Andric 
57510b57cec5SDimitry Andric     // Unions are never base classes, and never have base classes.
57520b57cec5SDimitry Andric     // It doesn't matter if they are complete or not. See PR#41843
57530b57cec5SDimitry Andric     if (lhsRecord && lhsRecord->getDecl()->isUnion())
57540b57cec5SDimitry Andric       return false;
57550b57cec5SDimitry Andric     if (rhsRecord && rhsRecord->getDecl()->isUnion())
57560b57cec5SDimitry Andric       return false;
57570b57cec5SDimitry Andric 
57580b57cec5SDimitry Andric     if (lhsRecord == rhsRecord)
57590b57cec5SDimitry Andric       return true;
57600b57cec5SDimitry Andric 
57610b57cec5SDimitry Andric     // C++0x [meta.rel]p2:
57620b57cec5SDimitry Andric     //   If Base and Derived are class types and are different types
57630b57cec5SDimitry Andric     //   (ignoring possible cv-qualifiers) then Derived shall be a
57640b57cec5SDimitry Andric     //   complete type.
57650b57cec5SDimitry Andric     if (Self.RequireCompleteType(KeyLoc, RhsT,
57660b57cec5SDimitry Andric                           diag::err_incomplete_type_used_in_type_trait_expr))
57670b57cec5SDimitry Andric       return false;
57680b57cec5SDimitry Andric 
57690b57cec5SDimitry Andric     return cast<CXXRecordDecl>(rhsRecord->getDecl())
57700b57cec5SDimitry Andric       ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));
57710b57cec5SDimitry Andric   }
57720b57cec5SDimitry Andric   case BTT_IsSame:
57730b57cec5SDimitry Andric     return Self.Context.hasSameType(LhsT, RhsT);
57740b57cec5SDimitry Andric   case BTT_TypeCompatible: {
57750b57cec5SDimitry Andric     // GCC ignores cv-qualifiers on arrays for this builtin.
57760b57cec5SDimitry Andric     Qualifiers LhsQuals, RhsQuals;
57770b57cec5SDimitry Andric     QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
57780b57cec5SDimitry Andric     QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
57790b57cec5SDimitry Andric     return Self.Context.typesAreCompatible(Lhs, Rhs);
57800b57cec5SDimitry Andric   }
57810b57cec5SDimitry Andric   case BTT_IsConvertible:
57820b57cec5SDimitry Andric   case BTT_IsConvertibleTo: {
57830b57cec5SDimitry Andric     // C++0x [meta.rel]p4:
57840b57cec5SDimitry Andric     //   Given the following function prototype:
57850b57cec5SDimitry Andric     //
57860b57cec5SDimitry Andric     //     template <class T>
57870b57cec5SDimitry Andric     //       typename add_rvalue_reference<T>::type create();
57880b57cec5SDimitry Andric     //
57890b57cec5SDimitry Andric     //   the predicate condition for a template specialization
57900b57cec5SDimitry Andric     //   is_convertible<From, To> shall be satisfied if and only if
57910b57cec5SDimitry Andric     //   the return expression in the following code would be
57920b57cec5SDimitry Andric     //   well-formed, including any implicit conversions to the return
57930b57cec5SDimitry Andric     //   type of the function:
57940b57cec5SDimitry Andric     //
57950b57cec5SDimitry Andric     //     To test() {
57960b57cec5SDimitry Andric     //       return create<From>();
57970b57cec5SDimitry Andric     //     }
57980b57cec5SDimitry Andric     //
57990b57cec5SDimitry Andric     //   Access checking is performed as if in a context unrelated to To and
58000b57cec5SDimitry Andric     //   From. Only the validity of the immediate context of the expression
58010b57cec5SDimitry Andric     //   of the return-statement (including conversions to the return type)
58020b57cec5SDimitry Andric     //   is considered.
58030b57cec5SDimitry Andric     //
58040b57cec5SDimitry Andric     // We model the initialization as a copy-initialization of a temporary
58050b57cec5SDimitry Andric     // of the appropriate type, which for this expression is identical to the
58060b57cec5SDimitry Andric     // return statement (since NRVO doesn't apply).
58070b57cec5SDimitry Andric 
58080b57cec5SDimitry Andric     // Functions aren't allowed to return function or array types.
58090b57cec5SDimitry Andric     if (RhsT->isFunctionType() || RhsT->isArrayType())
58100b57cec5SDimitry Andric       return false;
58110b57cec5SDimitry Andric 
58120b57cec5SDimitry Andric     // A return statement in a void function must have void type.
58130b57cec5SDimitry Andric     if (RhsT->isVoidType())
58140b57cec5SDimitry Andric       return LhsT->isVoidType();
58150b57cec5SDimitry Andric 
58160b57cec5SDimitry Andric     // A function definition requires a complete, non-abstract return type.
58170b57cec5SDimitry Andric     if (!Self.isCompleteType(KeyLoc, RhsT) || Self.isAbstractType(KeyLoc, RhsT))
58180b57cec5SDimitry Andric       return false;
58190b57cec5SDimitry Andric 
58200b57cec5SDimitry Andric     // Compute the result of add_rvalue_reference.
58210b57cec5SDimitry Andric     if (LhsT->isObjectType() || LhsT->isFunctionType())
58220b57cec5SDimitry Andric       LhsT = Self.Context.getRValueReferenceType(LhsT);
58230b57cec5SDimitry Andric 
58240b57cec5SDimitry Andric     // Build a fake source and destination for initialization.
58250b57cec5SDimitry Andric     InitializedEntity To(InitializedEntity::InitializeTemporary(RhsT));
58260b57cec5SDimitry Andric     OpaqueValueExpr From(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
58270b57cec5SDimitry Andric                          Expr::getValueKindForType(LhsT));
58280b57cec5SDimitry Andric     Expr *FromPtr = &From;
58290b57cec5SDimitry Andric     InitializationKind Kind(InitializationKind::CreateCopy(KeyLoc,
58300b57cec5SDimitry Andric                                                            SourceLocation()));
58310b57cec5SDimitry Andric 
58320b57cec5SDimitry Andric     // Perform the initialization in an unevaluated context within a SFINAE
58330b57cec5SDimitry Andric     // trap at translation unit scope.
58340b57cec5SDimitry Andric     EnterExpressionEvaluationContext Unevaluated(
58350b57cec5SDimitry Andric         Self, Sema::ExpressionEvaluationContext::Unevaluated);
58360b57cec5SDimitry Andric     Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true);
58370b57cec5SDimitry Andric     Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
58380b57cec5SDimitry Andric     InitializationSequence Init(Self, To, Kind, FromPtr);
58390b57cec5SDimitry Andric     if (Init.Failed())
58400b57cec5SDimitry Andric       return false;
58410b57cec5SDimitry Andric 
58420b57cec5SDimitry Andric     ExprResult Result = Init.Perform(Self, To, Kind, FromPtr);
58430b57cec5SDimitry Andric     return !Result.isInvalid() && !SFINAE.hasErrorOccurred();
58440b57cec5SDimitry Andric   }
58450b57cec5SDimitry Andric 
58460b57cec5SDimitry Andric   case BTT_IsAssignable:
58470b57cec5SDimitry Andric   case BTT_IsNothrowAssignable:
58480b57cec5SDimitry Andric   case BTT_IsTriviallyAssignable: {
58490b57cec5SDimitry Andric     // C++11 [meta.unary.prop]p3:
58500b57cec5SDimitry Andric     //   is_trivially_assignable is defined as:
58510b57cec5SDimitry Andric     //     is_assignable<T, U>::value is true and the assignment, as defined by
58520b57cec5SDimitry Andric     //     is_assignable, is known to call no operation that is not trivial
58530b57cec5SDimitry Andric     //
58540b57cec5SDimitry Andric     //   is_assignable is defined as:
58550b57cec5SDimitry Andric     //     The expression declval<T>() = declval<U>() is well-formed when
58560b57cec5SDimitry Andric     //     treated as an unevaluated operand (Clause 5).
58570b57cec5SDimitry Andric     //
58580b57cec5SDimitry Andric     //   For both, T and U shall be complete types, (possibly cv-qualified)
58590b57cec5SDimitry Andric     //   void, or arrays of unknown bound.
58600b57cec5SDimitry Andric     if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
58610b57cec5SDimitry Andric         Self.RequireCompleteType(KeyLoc, LhsT,
58620b57cec5SDimitry Andric           diag::err_incomplete_type_used_in_type_trait_expr))
58630b57cec5SDimitry Andric       return false;
58640b57cec5SDimitry Andric     if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
58650b57cec5SDimitry Andric         Self.RequireCompleteType(KeyLoc, RhsT,
58660b57cec5SDimitry Andric           diag::err_incomplete_type_used_in_type_trait_expr))
58670b57cec5SDimitry Andric       return false;
58680b57cec5SDimitry Andric 
58690b57cec5SDimitry Andric     // cv void is never assignable.
58700b57cec5SDimitry Andric     if (LhsT->isVoidType() || RhsT->isVoidType())
58710b57cec5SDimitry Andric       return false;
58720b57cec5SDimitry Andric 
58730b57cec5SDimitry Andric     // Build expressions that emulate the effect of declval<T>() and
58740b57cec5SDimitry Andric     // declval<U>().
58750b57cec5SDimitry Andric     if (LhsT->isObjectType() || LhsT->isFunctionType())
58760b57cec5SDimitry Andric       LhsT = Self.Context.getRValueReferenceType(LhsT);
58770b57cec5SDimitry Andric     if (RhsT->isObjectType() || RhsT->isFunctionType())
58780b57cec5SDimitry Andric       RhsT = Self.Context.getRValueReferenceType(RhsT);
58790b57cec5SDimitry Andric     OpaqueValueExpr Lhs(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
58800b57cec5SDimitry Andric                         Expr::getValueKindForType(LhsT));
58810b57cec5SDimitry Andric     OpaqueValueExpr Rhs(KeyLoc, RhsT.getNonLValueExprType(Self.Context),
58820b57cec5SDimitry Andric                         Expr::getValueKindForType(RhsT));
58830b57cec5SDimitry Andric 
58840b57cec5SDimitry Andric     // Attempt the assignment in an unevaluated context within a SFINAE
58850b57cec5SDimitry Andric     // trap at translation unit scope.
58860b57cec5SDimitry Andric     EnterExpressionEvaluationContext Unevaluated(
58870b57cec5SDimitry Andric         Self, Sema::ExpressionEvaluationContext::Unevaluated);
58880b57cec5SDimitry Andric     Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true);
58890b57cec5SDimitry Andric     Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
58900b57cec5SDimitry Andric     ExprResult Result = Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs,
58910b57cec5SDimitry Andric                                         &Rhs);
5892a7dea167SDimitry Andric     if (Result.isInvalid())
5893a7dea167SDimitry Andric       return false;
5894a7dea167SDimitry Andric 
5895a7dea167SDimitry Andric     // Treat the assignment as unused for the purpose of -Wdeprecated-volatile.
5896a7dea167SDimitry Andric     Self.CheckUnusedVolatileAssignment(Result.get());
5897a7dea167SDimitry Andric 
5898a7dea167SDimitry Andric     if (SFINAE.hasErrorOccurred())
58990b57cec5SDimitry Andric       return false;
59000b57cec5SDimitry Andric 
59010b57cec5SDimitry Andric     if (BTT == BTT_IsAssignable)
59020b57cec5SDimitry Andric       return true;
59030b57cec5SDimitry Andric 
59040b57cec5SDimitry Andric     if (BTT == BTT_IsNothrowAssignable)
59050b57cec5SDimitry Andric       return Self.canThrow(Result.get()) == CT_Cannot;
59060b57cec5SDimitry Andric 
59070b57cec5SDimitry Andric     if (BTT == BTT_IsTriviallyAssignable) {
59080b57cec5SDimitry Andric       // Under Objective-C ARC and Weak, if the destination has non-trivial
59090b57cec5SDimitry Andric       // Objective-C lifetime, this is a non-trivial assignment.
59100b57cec5SDimitry Andric       if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime())
59110b57cec5SDimitry Andric         return false;
59120b57cec5SDimitry Andric 
59130b57cec5SDimitry Andric       return !Result.get()->hasNonTrivialCall(Self.Context);
59140b57cec5SDimitry Andric     }
59150b57cec5SDimitry Andric 
59160b57cec5SDimitry Andric     llvm_unreachable("unhandled type trait");
59170b57cec5SDimitry Andric     return false;
59180b57cec5SDimitry Andric   }
59190b57cec5SDimitry Andric     default: llvm_unreachable("not a BTT");
59200b57cec5SDimitry Andric   }
59210b57cec5SDimitry Andric   llvm_unreachable("Unknown type trait or not implemented");
59220b57cec5SDimitry Andric }
59230b57cec5SDimitry Andric 
ActOnArrayTypeTrait(ArrayTypeTrait ATT,SourceLocation KWLoc,ParsedType Ty,Expr * DimExpr,SourceLocation RParen)59240b57cec5SDimitry Andric ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT,
59250b57cec5SDimitry Andric                                      SourceLocation KWLoc,
59260b57cec5SDimitry Andric                                      ParsedType Ty,
59270b57cec5SDimitry Andric                                      Expr* DimExpr,
59280b57cec5SDimitry Andric                                      SourceLocation RParen) {
59290b57cec5SDimitry Andric   TypeSourceInfo *TSInfo;
59300b57cec5SDimitry Andric   QualType T = GetTypeFromParser(Ty, &TSInfo);
59310b57cec5SDimitry Andric   if (!TSInfo)
59320b57cec5SDimitry Andric     TSInfo = Context.getTrivialTypeSourceInfo(T);
59330b57cec5SDimitry Andric 
59340b57cec5SDimitry Andric   return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
59350b57cec5SDimitry Andric }
59360b57cec5SDimitry Andric 
EvaluateArrayTypeTrait(Sema & Self,ArrayTypeTrait ATT,QualType T,Expr * DimExpr,SourceLocation KeyLoc)59370b57cec5SDimitry Andric static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT,
59380b57cec5SDimitry Andric                                            QualType T, Expr *DimExpr,
59390b57cec5SDimitry Andric                                            SourceLocation KeyLoc) {
59400b57cec5SDimitry Andric   assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
59410b57cec5SDimitry Andric 
59420b57cec5SDimitry Andric   switch(ATT) {
59430b57cec5SDimitry Andric   case ATT_ArrayRank:
59440b57cec5SDimitry Andric     if (T->isArrayType()) {
59450b57cec5SDimitry Andric       unsigned Dim = 0;
59460b57cec5SDimitry Andric       while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
59470b57cec5SDimitry Andric         ++Dim;
59480b57cec5SDimitry Andric         T = AT->getElementType();
59490b57cec5SDimitry Andric       }
59500b57cec5SDimitry Andric       return Dim;
59510b57cec5SDimitry Andric     }
59520b57cec5SDimitry Andric     return 0;
59530b57cec5SDimitry Andric 
59540b57cec5SDimitry Andric   case ATT_ArrayExtent: {
59550b57cec5SDimitry Andric     llvm::APSInt Value;
59560b57cec5SDimitry Andric     uint64_t Dim;
5957e8d8bef9SDimitry Andric     if (Self.VerifyIntegerConstantExpression(
5958e8d8bef9SDimitry Andric                 DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)
5959e8d8bef9SDimitry Andric             .isInvalid())
59600b57cec5SDimitry Andric       return 0;
59610b57cec5SDimitry Andric     if (Value.isSigned() && Value.isNegative()) {
59620b57cec5SDimitry Andric       Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
59630b57cec5SDimitry Andric         << DimExpr->getSourceRange();
59640b57cec5SDimitry Andric       return 0;
59650b57cec5SDimitry Andric     }
59660b57cec5SDimitry Andric     Dim = Value.getLimitedValue();
59670b57cec5SDimitry Andric 
59680b57cec5SDimitry Andric     if (T->isArrayType()) {
59690b57cec5SDimitry Andric       unsigned D = 0;
59700b57cec5SDimitry Andric       bool Matched = false;
59710b57cec5SDimitry Andric       while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
59720b57cec5SDimitry Andric         if (Dim == D) {
59730b57cec5SDimitry Andric           Matched = true;
59740b57cec5SDimitry Andric           break;
59750b57cec5SDimitry Andric         }
59760b57cec5SDimitry Andric         ++D;
59770b57cec5SDimitry Andric         T = AT->getElementType();
59780b57cec5SDimitry Andric       }
59790b57cec5SDimitry Andric 
59800b57cec5SDimitry Andric       if (Matched && T->isArrayType()) {
59810b57cec5SDimitry Andric         if (const ConstantArrayType *CAT = Self.Context.getAsConstantArrayType(T))
59820b57cec5SDimitry Andric           return CAT->getSize().getLimitedValue();
59830b57cec5SDimitry Andric       }
59840b57cec5SDimitry Andric     }
59850b57cec5SDimitry Andric     return 0;
59860b57cec5SDimitry Andric   }
59870b57cec5SDimitry Andric   }
59880b57cec5SDimitry Andric   llvm_unreachable("Unknown type trait or not implemented");
59890b57cec5SDimitry Andric }
59900b57cec5SDimitry Andric 
BuildArrayTypeTrait(ArrayTypeTrait ATT,SourceLocation KWLoc,TypeSourceInfo * TSInfo,Expr * DimExpr,SourceLocation RParen)59910b57cec5SDimitry Andric ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT,
59920b57cec5SDimitry Andric                                      SourceLocation KWLoc,
59930b57cec5SDimitry Andric                                      TypeSourceInfo *TSInfo,
59940b57cec5SDimitry Andric                                      Expr* DimExpr,
59950b57cec5SDimitry Andric                                      SourceLocation RParen) {
59960b57cec5SDimitry Andric   QualType T = TSInfo->getType();
59970b57cec5SDimitry Andric 
59980b57cec5SDimitry Andric   // FIXME: This should likely be tracked as an APInt to remove any host
59990b57cec5SDimitry Andric   // assumptions about the width of size_t on the target.
60000b57cec5SDimitry Andric   uint64_t Value = 0;
60010b57cec5SDimitry Andric   if (!T->isDependentType())
60020b57cec5SDimitry Andric     Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);
60030b57cec5SDimitry Andric 
60040b57cec5SDimitry Andric   // While the specification for these traits from the Embarcadero C++
60050b57cec5SDimitry Andric   // compiler's documentation says the return type is 'unsigned int', Clang
60060b57cec5SDimitry Andric   // returns 'size_t'. On Windows, the primary platform for the Embarcadero
60070b57cec5SDimitry Andric   // compiler, there is no difference. On several other platforms this is an
60080b57cec5SDimitry Andric   // important distinction.
60090b57cec5SDimitry Andric   return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
60100b57cec5SDimitry Andric                                           RParen, Context.getSizeType());
60110b57cec5SDimitry Andric }
60120b57cec5SDimitry Andric 
ActOnExpressionTrait(ExpressionTrait ET,SourceLocation KWLoc,Expr * Queried,SourceLocation RParen)60130b57cec5SDimitry Andric ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET,
60140b57cec5SDimitry Andric                                       SourceLocation KWLoc,
60150b57cec5SDimitry Andric                                       Expr *Queried,
60160b57cec5SDimitry Andric                                       SourceLocation RParen) {
60170b57cec5SDimitry Andric   // If error parsing the expression, ignore.
60180b57cec5SDimitry Andric   if (!Queried)
60190b57cec5SDimitry Andric     return ExprError();
60200b57cec5SDimitry Andric 
60210b57cec5SDimitry Andric   ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen);
60220b57cec5SDimitry Andric 
60230b57cec5SDimitry Andric   return Result;
60240b57cec5SDimitry Andric }
60250b57cec5SDimitry Andric 
EvaluateExpressionTrait(ExpressionTrait ET,Expr * E)60260b57cec5SDimitry Andric static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E) {
60270b57cec5SDimitry Andric   switch (ET) {
60280b57cec5SDimitry Andric   case ET_IsLValueExpr: return E->isLValue();
6029fe6060f1SDimitry Andric   case ET_IsRValueExpr:
6030fe6060f1SDimitry Andric     return E->isPRValue();
60310b57cec5SDimitry Andric   }
60320b57cec5SDimitry Andric   llvm_unreachable("Expression trait not covered by switch");
60330b57cec5SDimitry Andric }
60340b57cec5SDimitry Andric 
BuildExpressionTrait(ExpressionTrait ET,SourceLocation KWLoc,Expr * Queried,SourceLocation RParen)60350b57cec5SDimitry Andric ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET,
60360b57cec5SDimitry Andric                                       SourceLocation KWLoc,
60370b57cec5SDimitry Andric                                       Expr *Queried,
60380b57cec5SDimitry Andric                                       SourceLocation RParen) {
60390b57cec5SDimitry Andric   if (Queried->isTypeDependent()) {
60400b57cec5SDimitry Andric     // Delay type-checking for type-dependent expressions.
60411fd87a68SDimitry Andric   } else if (Queried->hasPlaceholderType()) {
60420b57cec5SDimitry Andric     ExprResult PE = CheckPlaceholderExpr(Queried);
60430b57cec5SDimitry Andric     if (PE.isInvalid()) return ExprError();
60440b57cec5SDimitry Andric     return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
60450b57cec5SDimitry Andric   }
60460b57cec5SDimitry Andric 
60470b57cec5SDimitry Andric   bool Value = EvaluateExpressionTrait(ET, Queried);
60480b57cec5SDimitry Andric 
60490b57cec5SDimitry Andric   return new (Context)
60500b57cec5SDimitry Andric       ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
60510b57cec5SDimitry Andric }
60520b57cec5SDimitry Andric 
CheckPointerToMemberOperands(ExprResult & LHS,ExprResult & RHS,ExprValueKind & VK,SourceLocation Loc,bool isIndirect)60530b57cec5SDimitry Andric QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
60540b57cec5SDimitry Andric                                             ExprValueKind &VK,
60550b57cec5SDimitry Andric                                             SourceLocation Loc,
60560b57cec5SDimitry Andric                                             bool isIndirect) {
60571fd87a68SDimitry Andric   assert(!LHS.get()->hasPlaceholderType() && !RHS.get()->hasPlaceholderType() &&
60580b57cec5SDimitry Andric          "placeholders should have been weeded out by now");
60590b57cec5SDimitry Andric 
60600b57cec5SDimitry Andric   // The LHS undergoes lvalue conversions if this is ->*, and undergoes the
60610b57cec5SDimitry Andric   // temporary materialization conversion otherwise.
60620b57cec5SDimitry Andric   if (isIndirect)
60630b57cec5SDimitry Andric     LHS = DefaultLvalueConversion(LHS.get());
6064fe6060f1SDimitry Andric   else if (LHS.get()->isPRValue())
60650b57cec5SDimitry Andric     LHS = TemporaryMaterializationConversion(LHS.get());
60660b57cec5SDimitry Andric   if (LHS.isInvalid())
60670b57cec5SDimitry Andric     return QualType();
60680b57cec5SDimitry Andric 
60690b57cec5SDimitry Andric   // The RHS always undergoes lvalue conversions.
60700b57cec5SDimitry Andric   RHS = DefaultLvalueConversion(RHS.get());
60710b57cec5SDimitry Andric   if (RHS.isInvalid()) return QualType();
60720b57cec5SDimitry Andric 
60730b57cec5SDimitry Andric   const char *OpSpelling = isIndirect ? "->*" : ".*";
60740b57cec5SDimitry Andric   // C++ 5.5p2
60750b57cec5SDimitry Andric   //   The binary operator .* [p3: ->*] binds its second operand, which shall
60760b57cec5SDimitry Andric   //   be of type "pointer to member of T" (where T is a completely-defined
60770b57cec5SDimitry Andric   //   class type) [...]
60780b57cec5SDimitry Andric   QualType RHSType = RHS.get()->getType();
60790b57cec5SDimitry Andric   const MemberPointerType *MemPtr = RHSType->getAs<MemberPointerType>();
60800b57cec5SDimitry Andric   if (!MemPtr) {
60810b57cec5SDimitry Andric     Diag(Loc, diag::err_bad_memptr_rhs)
60820b57cec5SDimitry Andric       << OpSpelling << RHSType << RHS.get()->getSourceRange();
60830b57cec5SDimitry Andric     return QualType();
60840b57cec5SDimitry Andric   }
60850b57cec5SDimitry Andric 
60860b57cec5SDimitry Andric   QualType Class(MemPtr->getClass(), 0);
60870b57cec5SDimitry Andric 
60880b57cec5SDimitry Andric   // Note: C++ [expr.mptr.oper]p2-3 says that the class type into which the
60890b57cec5SDimitry Andric   // member pointer points must be completely-defined. However, there is no
60900b57cec5SDimitry Andric   // reason for this semantic distinction, and the rule is not enforced by
60910b57cec5SDimitry Andric   // other compilers. Therefore, we do not check this property, as it is
60920b57cec5SDimitry Andric   // likely to be considered a defect.
60930b57cec5SDimitry Andric 
60940b57cec5SDimitry Andric   // C++ 5.5p2
60950b57cec5SDimitry Andric   //   [...] to its first operand, which shall be of class T or of a class of
60960b57cec5SDimitry Andric   //   which T is an unambiguous and accessible base class. [p3: a pointer to
60970b57cec5SDimitry Andric   //   such a class]
60980b57cec5SDimitry Andric   QualType LHSType = LHS.get()->getType();
60990b57cec5SDimitry Andric   if (isIndirect) {
61000b57cec5SDimitry Andric     if (const PointerType *Ptr = LHSType->getAs<PointerType>())
61010b57cec5SDimitry Andric       LHSType = Ptr->getPointeeType();
61020b57cec5SDimitry Andric     else {
61030b57cec5SDimitry Andric       Diag(Loc, diag::err_bad_memptr_lhs)
61040b57cec5SDimitry Andric         << OpSpelling << 1 << LHSType
61050b57cec5SDimitry Andric         << FixItHint::CreateReplacement(SourceRange(Loc), ".*");
61060b57cec5SDimitry Andric       return QualType();
61070b57cec5SDimitry Andric     }
61080b57cec5SDimitry Andric   }
61090b57cec5SDimitry Andric 
61100b57cec5SDimitry Andric   if (!Context.hasSameUnqualifiedType(Class, LHSType)) {
61110b57cec5SDimitry Andric     // If we want to check the hierarchy, we need a complete type.
61120b57cec5SDimitry Andric     if (RequireCompleteType(Loc, LHSType, diag::err_bad_memptr_lhs,
61130b57cec5SDimitry Andric                             OpSpelling, (int)isIndirect)) {
61140b57cec5SDimitry Andric       return QualType();
61150b57cec5SDimitry Andric     }
61160b57cec5SDimitry Andric 
61170b57cec5SDimitry Andric     if (!IsDerivedFrom(Loc, LHSType, Class)) {
61180b57cec5SDimitry Andric       Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling
61190b57cec5SDimitry Andric         << (int)isIndirect << LHS.get()->getType();
61200b57cec5SDimitry Andric       return QualType();
61210b57cec5SDimitry Andric     }
61220b57cec5SDimitry Andric 
61230b57cec5SDimitry Andric     CXXCastPath BasePath;
61240b57cec5SDimitry Andric     if (CheckDerivedToBaseConversion(
61250b57cec5SDimitry Andric             LHSType, Class, Loc,
61260b57cec5SDimitry Andric             SourceRange(LHS.get()->getBeginLoc(), RHS.get()->getEndLoc()),
61270b57cec5SDimitry Andric             &BasePath))
61280b57cec5SDimitry Andric       return QualType();
61290b57cec5SDimitry Andric 
61300b57cec5SDimitry Andric     // Cast LHS to type of use.
61310b57cec5SDimitry Andric     QualType UseType = Context.getQualifiedType(Class, LHSType.getQualifiers());
61320b57cec5SDimitry Andric     if (isIndirect)
61330b57cec5SDimitry Andric       UseType = Context.getPointerType(UseType);
6134fe6060f1SDimitry Andric     ExprValueKind VK = isIndirect ? VK_PRValue : LHS.get()->getValueKind();
61350b57cec5SDimitry Andric     LHS = ImpCastExprToType(LHS.get(), UseType, CK_DerivedToBase, VK,
61360b57cec5SDimitry Andric                             &BasePath);
61370b57cec5SDimitry Andric   }
61380b57cec5SDimitry Andric 
61390b57cec5SDimitry Andric   if (isa<CXXScalarValueInitExpr>(RHS.get()->IgnoreParens())) {
61400b57cec5SDimitry Andric     // Diagnose use of pointer-to-member type which when used as
61410b57cec5SDimitry Andric     // the functional cast in a pointer-to-member expression.
61420b57cec5SDimitry Andric     Diag(Loc, diag::err_pointer_to_member_type) << isIndirect;
61430b57cec5SDimitry Andric      return QualType();
61440b57cec5SDimitry Andric   }
61450b57cec5SDimitry Andric 
61460b57cec5SDimitry Andric   // C++ 5.5p2
61470b57cec5SDimitry Andric   //   The result is an object or a function of the type specified by the
61480b57cec5SDimitry Andric   //   second operand.
61490b57cec5SDimitry Andric   // The cv qualifiers are the union of those in the pointer and the left side,
61500b57cec5SDimitry Andric   // in accordance with 5.5p5 and 5.2.5.
61510b57cec5SDimitry Andric   QualType Result = MemPtr->getPointeeType();
61520b57cec5SDimitry Andric   Result = Context.getCVRQualifiedType(Result, LHSType.getCVRQualifiers());
61530b57cec5SDimitry Andric 
61540b57cec5SDimitry Andric   // C++0x [expr.mptr.oper]p6:
61550b57cec5SDimitry Andric   //   In a .* expression whose object expression is an rvalue, the program is
61560b57cec5SDimitry Andric   //   ill-formed if the second operand is a pointer to member function with
61570b57cec5SDimitry Andric   //   ref-qualifier &. In a ->* expression or in a .* expression whose object
61580b57cec5SDimitry Andric   //   expression is an lvalue, the program is ill-formed if the second operand
61590b57cec5SDimitry Andric   //   is a pointer to member function with ref-qualifier &&.
61600b57cec5SDimitry Andric   if (const FunctionProtoType *Proto = Result->getAs<FunctionProtoType>()) {
61610b57cec5SDimitry Andric     switch (Proto->getRefQualifier()) {
61620b57cec5SDimitry Andric     case RQ_None:
61630b57cec5SDimitry Andric       // Do nothing
61640b57cec5SDimitry Andric       break;
61650b57cec5SDimitry Andric 
61660b57cec5SDimitry Andric     case RQ_LValue:
61670b57cec5SDimitry Andric       if (!isIndirect && !LHS.get()->Classify(Context).isLValue()) {
61680b57cec5SDimitry Andric         // C++2a allows functions with ref-qualifier & if their cv-qualifier-seq
61690b57cec5SDimitry Andric         // is (exactly) 'const'.
61700b57cec5SDimitry Andric         if (Proto->isConst() && !Proto->isVolatile())
61715ffd83dbSDimitry Andric           Diag(Loc, getLangOpts().CPlusPlus20
61720b57cec5SDimitry Andric                         ? diag::warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue
61730b57cec5SDimitry Andric                         : diag::ext_pointer_to_const_ref_member_on_rvalue);
61740b57cec5SDimitry Andric         else
61750b57cec5SDimitry Andric           Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
61760b57cec5SDimitry Andric               << RHSType << 1 << LHS.get()->getSourceRange();
61770b57cec5SDimitry Andric       }
61780b57cec5SDimitry Andric       break;
61790b57cec5SDimitry Andric 
61800b57cec5SDimitry Andric     case RQ_RValue:
61810b57cec5SDimitry Andric       if (isIndirect || !LHS.get()->Classify(Context).isRValue())
61820b57cec5SDimitry Andric         Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
61830b57cec5SDimitry Andric           << RHSType << 0 << LHS.get()->getSourceRange();
61840b57cec5SDimitry Andric       break;
61850b57cec5SDimitry Andric     }
61860b57cec5SDimitry Andric   }
61870b57cec5SDimitry Andric 
61880b57cec5SDimitry Andric   // C++ [expr.mptr.oper]p6:
61890b57cec5SDimitry Andric   //   The result of a .* expression whose second operand is a pointer
61900b57cec5SDimitry Andric   //   to a data member is of the same value category as its
61910b57cec5SDimitry Andric   //   first operand. The result of a .* expression whose second
61920b57cec5SDimitry Andric   //   operand is a pointer to a member function is a prvalue. The
61930b57cec5SDimitry Andric   //   result of an ->* expression is an lvalue if its second operand
61940b57cec5SDimitry Andric   //   is a pointer to data member and a prvalue otherwise.
61950b57cec5SDimitry Andric   if (Result->isFunctionType()) {
6196fe6060f1SDimitry Andric     VK = VK_PRValue;
61970b57cec5SDimitry Andric     return Context.BoundMemberTy;
61980b57cec5SDimitry Andric   } else if (isIndirect) {
61990b57cec5SDimitry Andric     VK = VK_LValue;
62000b57cec5SDimitry Andric   } else {
62010b57cec5SDimitry Andric     VK = LHS.get()->getValueKind();
62020b57cec5SDimitry Andric   }
62030b57cec5SDimitry Andric 
62040b57cec5SDimitry Andric   return Result;
62050b57cec5SDimitry Andric }
62060b57cec5SDimitry Andric 
62070b57cec5SDimitry Andric /// Try to convert a type to another according to C++11 5.16p3.
62080b57cec5SDimitry Andric ///
62090b57cec5SDimitry Andric /// This is part of the parameter validation for the ? operator. If either
62100b57cec5SDimitry Andric /// value operand is a class type, the two operands are attempted to be
62110b57cec5SDimitry Andric /// converted to each other. This function does the conversion in one direction.
62120b57cec5SDimitry Andric /// It returns true if the program is ill-formed and has already been diagnosed
62130b57cec5SDimitry Andric /// as such.
TryClassUnification(Sema & Self,Expr * From,Expr * To,SourceLocation QuestionLoc,bool & HaveConversion,QualType & ToType)62140b57cec5SDimitry Andric static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
62150b57cec5SDimitry Andric                                 SourceLocation QuestionLoc,
62160b57cec5SDimitry Andric                                 bool &HaveConversion,
62170b57cec5SDimitry Andric                                 QualType &ToType) {
62180b57cec5SDimitry Andric   HaveConversion = false;
62190b57cec5SDimitry Andric   ToType = To->getType();
62200b57cec5SDimitry Andric 
62210b57cec5SDimitry Andric   InitializationKind Kind =
62220b57cec5SDimitry Andric       InitializationKind::CreateCopy(To->getBeginLoc(), SourceLocation());
62230b57cec5SDimitry Andric   // C++11 5.16p3
62240b57cec5SDimitry Andric   //   The process for determining whether an operand expression E1 of type T1
62250b57cec5SDimitry Andric   //   can be converted to match an operand expression E2 of type T2 is defined
62260b57cec5SDimitry Andric   //   as follows:
62270b57cec5SDimitry Andric   //   -- If E2 is an lvalue: E1 can be converted to match E2 if E1 can be
62280b57cec5SDimitry Andric   //      implicitly converted to type "lvalue reference to T2", subject to the
62290b57cec5SDimitry Andric   //      constraint that in the conversion the reference must bind directly to
62300b57cec5SDimitry Andric   //      an lvalue.
62310b57cec5SDimitry Andric   //   -- If E2 is an xvalue: E1 can be converted to match E2 if E1 can be
62320b57cec5SDimitry Andric   //      implicitly converted to the type "rvalue reference to R2", subject to
62330b57cec5SDimitry Andric   //      the constraint that the reference must bind directly.
6234349cc55cSDimitry Andric   if (To->isGLValue()) {
6235349cc55cSDimitry Andric     QualType T = Self.Context.getReferenceQualifiedType(To);
62360b57cec5SDimitry Andric     InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
62370b57cec5SDimitry Andric 
62380b57cec5SDimitry Andric     InitializationSequence InitSeq(Self, Entity, Kind, From);
62390b57cec5SDimitry Andric     if (InitSeq.isDirectReferenceBinding()) {
62400b57cec5SDimitry Andric       ToType = T;
62410b57cec5SDimitry Andric       HaveConversion = true;
62420b57cec5SDimitry Andric       return false;
62430b57cec5SDimitry Andric     }
62440b57cec5SDimitry Andric 
62450b57cec5SDimitry Andric     if (InitSeq.isAmbiguous())
62460b57cec5SDimitry Andric       return InitSeq.Diagnose(Self, Entity, Kind, From);
62470b57cec5SDimitry Andric   }
62480b57cec5SDimitry Andric 
62490b57cec5SDimitry Andric   //   -- If E2 is an rvalue, or if the conversion above cannot be done:
62500b57cec5SDimitry Andric   //      -- if E1 and E2 have class type, and the underlying class types are
62510b57cec5SDimitry Andric   //         the same or one is a base class of the other:
62520b57cec5SDimitry Andric   QualType FTy = From->getType();
62530b57cec5SDimitry Andric   QualType TTy = To->getType();
62540b57cec5SDimitry Andric   const RecordType *FRec = FTy->getAs<RecordType>();
62550b57cec5SDimitry Andric   const RecordType *TRec = TTy->getAs<RecordType>();
62560b57cec5SDimitry Andric   bool FDerivedFromT = FRec && TRec && FRec != TRec &&
62570b57cec5SDimitry Andric                        Self.IsDerivedFrom(QuestionLoc, FTy, TTy);
62580b57cec5SDimitry Andric   if (FRec && TRec && (FRec == TRec || FDerivedFromT ||
62590b57cec5SDimitry Andric                        Self.IsDerivedFrom(QuestionLoc, TTy, FTy))) {
62600b57cec5SDimitry Andric     //         E1 can be converted to match E2 if the class of T2 is the
62610b57cec5SDimitry Andric     //         same type as, or a base class of, the class of T1, and
62620b57cec5SDimitry Andric     //         [cv2 > cv1].
62630b57cec5SDimitry Andric     if (FRec == TRec || FDerivedFromT) {
62640b57cec5SDimitry Andric       if (TTy.isAtLeastAsQualifiedAs(FTy)) {
62650b57cec5SDimitry Andric         InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy);
62660b57cec5SDimitry Andric         InitializationSequence InitSeq(Self, Entity, Kind, From);
62670b57cec5SDimitry Andric         if (InitSeq) {
62680b57cec5SDimitry Andric           HaveConversion = true;
62690b57cec5SDimitry Andric           return false;
62700b57cec5SDimitry Andric         }
62710b57cec5SDimitry Andric 
62720b57cec5SDimitry Andric         if (InitSeq.isAmbiguous())
62730b57cec5SDimitry Andric           return InitSeq.Diagnose(Self, Entity, Kind, From);
62740b57cec5SDimitry Andric       }
62750b57cec5SDimitry Andric     }
62760b57cec5SDimitry Andric 
62770b57cec5SDimitry Andric     return false;
62780b57cec5SDimitry Andric   }
62790b57cec5SDimitry Andric 
62800b57cec5SDimitry Andric   //     -- Otherwise: E1 can be converted to match E2 if E1 can be
62810b57cec5SDimitry Andric   //        implicitly converted to the type that expression E2 would have
62820b57cec5SDimitry Andric   //        if E2 were converted to an rvalue (or the type it has, if E2 is
62830b57cec5SDimitry Andric   //        an rvalue).
62840b57cec5SDimitry Andric   //
62850b57cec5SDimitry Andric   // This actually refers very narrowly to the lvalue-to-rvalue conversion, not
62860b57cec5SDimitry Andric   // to the array-to-pointer or function-to-pointer conversions.
62870b57cec5SDimitry Andric   TTy = TTy.getNonLValueExprType(Self.Context);
62880b57cec5SDimitry Andric 
62890b57cec5SDimitry Andric   InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy);
62900b57cec5SDimitry Andric   InitializationSequence InitSeq(Self, Entity, Kind, From);
62910b57cec5SDimitry Andric   HaveConversion = !InitSeq.Failed();
62920b57cec5SDimitry Andric   ToType = TTy;
62930b57cec5SDimitry Andric   if (InitSeq.isAmbiguous())
62940b57cec5SDimitry Andric     return InitSeq.Diagnose(Self, Entity, Kind, From);
62950b57cec5SDimitry Andric 
62960b57cec5SDimitry Andric   return false;
62970b57cec5SDimitry Andric }
62980b57cec5SDimitry Andric 
62990b57cec5SDimitry Andric /// Try to find a common type for two according to C++0x 5.16p5.
63000b57cec5SDimitry Andric ///
63010b57cec5SDimitry Andric /// This is part of the parameter validation for the ? operator. If either
63020b57cec5SDimitry Andric /// value operand is a class type, overload resolution is used to find a
63030b57cec5SDimitry Andric /// conversion to a common type.
FindConditionalOverload(Sema & Self,ExprResult & LHS,ExprResult & RHS,SourceLocation QuestionLoc)63040b57cec5SDimitry Andric static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS,
63050b57cec5SDimitry Andric                                     SourceLocation QuestionLoc) {
63060b57cec5SDimitry Andric   Expr *Args[2] = { LHS.get(), RHS.get() };
63070b57cec5SDimitry Andric   OverloadCandidateSet CandidateSet(QuestionLoc,
63080b57cec5SDimitry Andric                                     OverloadCandidateSet::CSK_Operator);
63090b57cec5SDimitry Andric   Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args,
63100b57cec5SDimitry Andric                                     CandidateSet);
63110b57cec5SDimitry Andric 
63120b57cec5SDimitry Andric   OverloadCandidateSet::iterator Best;
63130b57cec5SDimitry Andric   switch (CandidateSet.BestViableFunction(Self, QuestionLoc, Best)) {
63140b57cec5SDimitry Andric     case OR_Success: {
63150b57cec5SDimitry Andric       // We found a match. Perform the conversions on the arguments and move on.
63160b57cec5SDimitry Andric       ExprResult LHSRes = Self.PerformImplicitConversion(
63170b57cec5SDimitry Andric           LHS.get(), Best->BuiltinParamTypes[0], Best->Conversions[0],
63180b57cec5SDimitry Andric           Sema::AA_Converting);
63190b57cec5SDimitry Andric       if (LHSRes.isInvalid())
63200b57cec5SDimitry Andric         break;
63210b57cec5SDimitry Andric       LHS = LHSRes;
63220b57cec5SDimitry Andric 
63230b57cec5SDimitry Andric       ExprResult RHSRes = Self.PerformImplicitConversion(
63240b57cec5SDimitry Andric           RHS.get(), Best->BuiltinParamTypes[1], Best->Conversions[1],
63250b57cec5SDimitry Andric           Sema::AA_Converting);
63260b57cec5SDimitry Andric       if (RHSRes.isInvalid())
63270b57cec5SDimitry Andric         break;
63280b57cec5SDimitry Andric       RHS = RHSRes;
63290b57cec5SDimitry Andric       if (Best->Function)
63300b57cec5SDimitry Andric         Self.MarkFunctionReferenced(QuestionLoc, Best->Function);
63310b57cec5SDimitry Andric       return false;
63320b57cec5SDimitry Andric     }
63330b57cec5SDimitry Andric 
63340b57cec5SDimitry Andric     case OR_No_Viable_Function:
63350b57cec5SDimitry Andric 
63360b57cec5SDimitry Andric       // Emit a better diagnostic if one of the expressions is a null pointer
63370b57cec5SDimitry Andric       // constant and the other is a pointer type. In this case, the user most
63380b57cec5SDimitry Andric       // likely forgot to take the address of the other expression.
63390b57cec5SDimitry Andric       if (Self.DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc))
63400b57cec5SDimitry Andric         return true;
63410b57cec5SDimitry Andric 
63420b57cec5SDimitry Andric       Self.Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
63430b57cec5SDimitry Andric         << LHS.get()->getType() << RHS.get()->getType()
63440b57cec5SDimitry Andric         << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
63450b57cec5SDimitry Andric       return true;
63460b57cec5SDimitry Andric 
63470b57cec5SDimitry Andric     case OR_Ambiguous:
63480b57cec5SDimitry Andric       Self.Diag(QuestionLoc, diag::err_conditional_ambiguous_ovl)
63490b57cec5SDimitry Andric         << LHS.get()->getType() << RHS.get()->getType()
63500b57cec5SDimitry Andric         << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
63510b57cec5SDimitry Andric       // FIXME: Print the possible common types by printing the return types of
63520b57cec5SDimitry Andric       // the viable candidates.
63530b57cec5SDimitry Andric       break;
63540b57cec5SDimitry Andric 
63550b57cec5SDimitry Andric     case OR_Deleted:
63560b57cec5SDimitry Andric       llvm_unreachable("Conditional operator has only built-in overloads");
63570b57cec5SDimitry Andric   }
63580b57cec5SDimitry Andric   return true;
63590b57cec5SDimitry Andric }
63600b57cec5SDimitry Andric 
63610b57cec5SDimitry Andric /// Perform an "extended" implicit conversion as returned by
63620b57cec5SDimitry Andric /// TryClassUnification.
ConvertForConditional(Sema & Self,ExprResult & E,QualType T)63630b57cec5SDimitry Andric static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) {
63640b57cec5SDimitry Andric   InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
63650b57cec5SDimitry Andric   InitializationKind Kind =
63660b57cec5SDimitry Andric       InitializationKind::CreateCopy(E.get()->getBeginLoc(), SourceLocation());
63670b57cec5SDimitry Andric   Expr *Arg = E.get();
63680b57cec5SDimitry Andric   InitializationSequence InitSeq(Self, Entity, Kind, Arg);
63690b57cec5SDimitry Andric   ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg);
63700b57cec5SDimitry Andric   if (Result.isInvalid())
63710b57cec5SDimitry Andric     return true;
63720b57cec5SDimitry Andric 
63730b57cec5SDimitry Andric   E = Result;
63740b57cec5SDimitry Andric   return false;
63750b57cec5SDimitry Andric }
63760b57cec5SDimitry Andric 
6377480093f4SDimitry Andric // Check the condition operand of ?: to see if it is valid for the GCC
6378480093f4SDimitry Andric // extension.
isValidVectorForConditionalCondition(ASTContext & Ctx,QualType CondTy)6379480093f4SDimitry Andric static bool isValidVectorForConditionalCondition(ASTContext &Ctx,
6380480093f4SDimitry Andric                                                  QualType CondTy) {
6381fe6060f1SDimitry Andric   if (!CondTy->isVectorType() && !CondTy->isExtVectorType())
6382480093f4SDimitry Andric     return false;
6383480093f4SDimitry Andric   const QualType EltTy =
6384480093f4SDimitry Andric       cast<VectorType>(CondTy.getCanonicalType())->getElementType();
638581ad6265SDimitry Andric   assert(!EltTy->isEnumeralType() && "Vectors cant be enum types");
638681ad6265SDimitry Andric   return EltTy->isIntegralType(Ctx);
638781ad6265SDimitry Andric }
638881ad6265SDimitry Andric 
isValidSizelessVectorForConditionalCondition(ASTContext & Ctx,QualType CondTy)638981ad6265SDimitry Andric static bool isValidSizelessVectorForConditionalCondition(ASTContext &Ctx,
639081ad6265SDimitry Andric                                                          QualType CondTy) {
63915f757f3fSDimitry Andric   if (!CondTy->isSveVLSBuiltinType())
639281ad6265SDimitry Andric     return false;
639381ad6265SDimitry Andric   const QualType EltTy =
639481ad6265SDimitry Andric       cast<BuiltinType>(CondTy.getCanonicalType())->getSveEltType(Ctx);
639581ad6265SDimitry Andric   assert(!EltTy->isEnumeralType() && "Vectors cant be enum types");
6396480093f4SDimitry Andric   return EltTy->isIntegralType(Ctx);
6397480093f4SDimitry Andric }
6398480093f4SDimitry Andric 
CheckVectorConditionalTypes(ExprResult & Cond,ExprResult & LHS,ExprResult & RHS,SourceLocation QuestionLoc)6399fe6060f1SDimitry Andric QualType Sema::CheckVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
6400480093f4SDimitry Andric                                            ExprResult &RHS,
6401480093f4SDimitry Andric                                            SourceLocation QuestionLoc) {
6402480093f4SDimitry Andric   LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
6403480093f4SDimitry Andric   RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
6404480093f4SDimitry Andric 
6405480093f4SDimitry Andric   QualType CondType = Cond.get()->getType();
64065ffd83dbSDimitry Andric   const auto *CondVT = CondType->castAs<VectorType>();
6407480093f4SDimitry Andric   QualType CondElementTy = CondVT->getElementType();
6408480093f4SDimitry Andric   unsigned CondElementCount = CondVT->getNumElements();
6409480093f4SDimitry Andric   QualType LHSType = LHS.get()->getType();
6410480093f4SDimitry Andric   const auto *LHSVT = LHSType->getAs<VectorType>();
6411480093f4SDimitry Andric   QualType RHSType = RHS.get()->getType();
6412480093f4SDimitry Andric   const auto *RHSVT = RHSType->getAs<VectorType>();
6413480093f4SDimitry Andric 
6414480093f4SDimitry Andric   QualType ResultType;
6415480093f4SDimitry Andric 
6416480093f4SDimitry Andric 
6417480093f4SDimitry Andric   if (LHSVT && RHSVT) {
6418fe6060f1SDimitry Andric     if (isa<ExtVectorType>(CondVT) != isa<ExtVectorType>(LHSVT)) {
6419fe6060f1SDimitry Andric       Diag(QuestionLoc, diag::err_conditional_vector_cond_result_mismatch)
6420fe6060f1SDimitry Andric           << /*isExtVector*/ isa<ExtVectorType>(CondVT);
6421fe6060f1SDimitry Andric       return {};
6422fe6060f1SDimitry Andric     }
6423fe6060f1SDimitry Andric 
6424480093f4SDimitry Andric     // If both are vector types, they must be the same type.
6425480093f4SDimitry Andric     if (!Context.hasSameType(LHSType, RHSType)) {
6426fe6060f1SDimitry Andric       Diag(QuestionLoc, diag::err_conditional_vector_mismatched)
6427480093f4SDimitry Andric           << LHSType << RHSType;
6428480093f4SDimitry Andric       return {};
6429480093f4SDimitry Andric     }
6430bdd1243dSDimitry Andric     ResultType = Context.getCommonSugaredType(LHSType, RHSType);
6431480093f4SDimitry Andric   } else if (LHSVT || RHSVT) {
6432480093f4SDimitry Andric     ResultType = CheckVectorOperands(
6433480093f4SDimitry Andric         LHS, RHS, QuestionLoc, /*isCompAssign*/ false, /*AllowBothBool*/ true,
643481ad6265SDimitry Andric         /*AllowBoolConversions*/ false,
643581ad6265SDimitry Andric         /*AllowBoolOperation*/ true,
643681ad6265SDimitry Andric         /*ReportInvalid*/ true);
6437480093f4SDimitry Andric     if (ResultType.isNull())
6438480093f4SDimitry Andric       return {};
6439480093f4SDimitry Andric   } else {
6440480093f4SDimitry Andric     // Both are scalar.
6441bdd1243dSDimitry Andric     LHSType = LHSType.getUnqualifiedType();
6442bdd1243dSDimitry Andric     RHSType = RHSType.getUnqualifiedType();
6443bdd1243dSDimitry Andric     QualType ResultElementTy =
6444bdd1243dSDimitry Andric         Context.hasSameType(LHSType, RHSType)
6445bdd1243dSDimitry Andric             ? Context.getCommonSugaredType(LHSType, RHSType)
6446bdd1243dSDimitry Andric             : UsualArithmeticConversions(LHS, RHS, QuestionLoc,
6447bdd1243dSDimitry Andric                                          ACK_Conditional);
6448480093f4SDimitry Andric 
6449480093f4SDimitry Andric     if (ResultElementTy->isEnumeralType()) {
6450480093f4SDimitry Andric       Diag(QuestionLoc, diag::err_conditional_vector_operand_type)
6451fe6060f1SDimitry Andric           << ResultElementTy;
6452480093f4SDimitry Andric       return {};
6453480093f4SDimitry Andric     }
6454fe6060f1SDimitry Andric     if (CondType->isExtVectorType())
6455fe6060f1SDimitry Andric       ResultType =
6456fe6060f1SDimitry Andric           Context.getExtVectorType(ResultElementTy, CondVT->getNumElements());
6457fe6060f1SDimitry Andric     else
6458480093f4SDimitry Andric       ResultType = Context.getVectorType(
64595f757f3fSDimitry Andric           ResultElementTy, CondVT->getNumElements(), VectorKind::Generic);
6460480093f4SDimitry Andric 
6461480093f4SDimitry Andric     LHS = ImpCastExprToType(LHS.get(), ResultType, CK_VectorSplat);
6462480093f4SDimitry Andric     RHS = ImpCastExprToType(RHS.get(), ResultType, CK_VectorSplat);
6463480093f4SDimitry Andric   }
6464480093f4SDimitry Andric 
6465480093f4SDimitry Andric   assert(!ResultType.isNull() && ResultType->isVectorType() &&
6466fe6060f1SDimitry Andric          (!CondType->isExtVectorType() || ResultType->isExtVectorType()) &&
6467480093f4SDimitry Andric          "Result should have been a vector type");
64685ffd83dbSDimitry Andric   auto *ResultVectorTy = ResultType->castAs<VectorType>();
64695ffd83dbSDimitry Andric   QualType ResultElementTy = ResultVectorTy->getElementType();
64705ffd83dbSDimitry Andric   unsigned ResultElementCount = ResultVectorTy->getNumElements();
6471480093f4SDimitry Andric 
6472480093f4SDimitry Andric   if (ResultElementCount != CondElementCount) {
6473480093f4SDimitry Andric     Diag(QuestionLoc, diag::err_conditional_vector_size) << CondType
6474480093f4SDimitry Andric                                                          << ResultType;
6475480093f4SDimitry Andric     return {};
6476480093f4SDimitry Andric   }
6477480093f4SDimitry Andric 
6478480093f4SDimitry Andric   if (Context.getTypeSize(ResultElementTy) !=
6479480093f4SDimitry Andric       Context.getTypeSize(CondElementTy)) {
6480480093f4SDimitry Andric     Diag(QuestionLoc, diag::err_conditional_vector_element_size) << CondType
6481480093f4SDimitry Andric                                                                  << ResultType;
6482480093f4SDimitry Andric     return {};
6483480093f4SDimitry Andric   }
6484480093f4SDimitry Andric 
6485480093f4SDimitry Andric   return ResultType;
6486480093f4SDimitry Andric }
6487480093f4SDimitry Andric 
CheckSizelessVectorConditionalTypes(ExprResult & Cond,ExprResult & LHS,ExprResult & RHS,SourceLocation QuestionLoc)648881ad6265SDimitry Andric QualType Sema::CheckSizelessVectorConditionalTypes(ExprResult &Cond,
648981ad6265SDimitry Andric                                                    ExprResult &LHS,
649081ad6265SDimitry Andric                                                    ExprResult &RHS,
649181ad6265SDimitry Andric                                                    SourceLocation QuestionLoc) {
649281ad6265SDimitry Andric   LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
649381ad6265SDimitry Andric   RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
649481ad6265SDimitry Andric 
649581ad6265SDimitry Andric   QualType CondType = Cond.get()->getType();
649681ad6265SDimitry Andric   const auto *CondBT = CondType->castAs<BuiltinType>();
649781ad6265SDimitry Andric   QualType CondElementTy = CondBT->getSveEltType(Context);
649881ad6265SDimitry Andric   llvm::ElementCount CondElementCount =
649981ad6265SDimitry Andric       Context.getBuiltinVectorTypeInfo(CondBT).EC;
650081ad6265SDimitry Andric 
650181ad6265SDimitry Andric   QualType LHSType = LHS.get()->getType();
650281ad6265SDimitry Andric   const auto *LHSBT =
65035f757f3fSDimitry Andric       LHSType->isSveVLSBuiltinType() ? LHSType->getAs<BuiltinType>() : nullptr;
650481ad6265SDimitry Andric   QualType RHSType = RHS.get()->getType();
650581ad6265SDimitry Andric   const auto *RHSBT =
65065f757f3fSDimitry Andric       RHSType->isSveVLSBuiltinType() ? RHSType->getAs<BuiltinType>() : nullptr;
650781ad6265SDimitry Andric 
650881ad6265SDimitry Andric   QualType ResultType;
650981ad6265SDimitry Andric 
651081ad6265SDimitry Andric   if (LHSBT && RHSBT) {
651181ad6265SDimitry Andric     // If both are sizeless vector types, they must be the same type.
651281ad6265SDimitry Andric     if (!Context.hasSameType(LHSType, RHSType)) {
651381ad6265SDimitry Andric       Diag(QuestionLoc, diag::err_conditional_vector_mismatched)
651481ad6265SDimitry Andric           << LHSType << RHSType;
651581ad6265SDimitry Andric       return QualType();
651681ad6265SDimitry Andric     }
651781ad6265SDimitry Andric     ResultType = LHSType;
651881ad6265SDimitry Andric   } else if (LHSBT || RHSBT) {
651981ad6265SDimitry Andric     ResultType = CheckSizelessVectorOperands(
652081ad6265SDimitry Andric         LHS, RHS, QuestionLoc, /*IsCompAssign*/ false, ACK_Conditional);
652181ad6265SDimitry Andric     if (ResultType.isNull())
652281ad6265SDimitry Andric       return QualType();
652381ad6265SDimitry Andric   } else {
652481ad6265SDimitry Andric     // Both are scalar so splat
652581ad6265SDimitry Andric     QualType ResultElementTy;
652681ad6265SDimitry Andric     LHSType = LHSType.getCanonicalType().getUnqualifiedType();
652781ad6265SDimitry Andric     RHSType = RHSType.getCanonicalType().getUnqualifiedType();
652881ad6265SDimitry Andric 
652981ad6265SDimitry Andric     if (Context.hasSameType(LHSType, RHSType))
653081ad6265SDimitry Andric       ResultElementTy = LHSType;
653181ad6265SDimitry Andric     else
653281ad6265SDimitry Andric       ResultElementTy =
653381ad6265SDimitry Andric           UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional);
653481ad6265SDimitry Andric 
653581ad6265SDimitry Andric     if (ResultElementTy->isEnumeralType()) {
653681ad6265SDimitry Andric       Diag(QuestionLoc, diag::err_conditional_vector_operand_type)
653781ad6265SDimitry Andric           << ResultElementTy;
653881ad6265SDimitry Andric       return QualType();
653981ad6265SDimitry Andric     }
654081ad6265SDimitry Andric 
654181ad6265SDimitry Andric     ResultType = Context.getScalableVectorType(
654281ad6265SDimitry Andric         ResultElementTy, CondElementCount.getKnownMinValue());
654381ad6265SDimitry Andric 
654481ad6265SDimitry Andric     LHS = ImpCastExprToType(LHS.get(), ResultType, CK_VectorSplat);
654581ad6265SDimitry Andric     RHS = ImpCastExprToType(RHS.get(), ResultType, CK_VectorSplat);
654681ad6265SDimitry Andric   }
654781ad6265SDimitry Andric 
65485f757f3fSDimitry Andric   assert(!ResultType.isNull() && ResultType->isSveVLSBuiltinType() &&
654981ad6265SDimitry Andric          "Result should have been a vector type");
655081ad6265SDimitry Andric   auto *ResultBuiltinTy = ResultType->castAs<BuiltinType>();
655181ad6265SDimitry Andric   QualType ResultElementTy = ResultBuiltinTy->getSveEltType(Context);
655281ad6265SDimitry Andric   llvm::ElementCount ResultElementCount =
655381ad6265SDimitry Andric       Context.getBuiltinVectorTypeInfo(ResultBuiltinTy).EC;
655481ad6265SDimitry Andric 
655581ad6265SDimitry Andric   if (ResultElementCount != CondElementCount) {
655681ad6265SDimitry Andric     Diag(QuestionLoc, diag::err_conditional_vector_size)
655781ad6265SDimitry Andric         << CondType << ResultType;
655881ad6265SDimitry Andric     return QualType();
655981ad6265SDimitry Andric   }
656081ad6265SDimitry Andric 
656181ad6265SDimitry Andric   if (Context.getTypeSize(ResultElementTy) !=
656281ad6265SDimitry Andric       Context.getTypeSize(CondElementTy)) {
656381ad6265SDimitry Andric     Diag(QuestionLoc, diag::err_conditional_vector_element_size)
656481ad6265SDimitry Andric         << CondType << ResultType;
656581ad6265SDimitry Andric     return QualType();
656681ad6265SDimitry Andric   }
656781ad6265SDimitry Andric 
656881ad6265SDimitry Andric   return ResultType;
656981ad6265SDimitry Andric }
657081ad6265SDimitry Andric 
65710b57cec5SDimitry Andric /// Check the operands of ?: under C++ semantics.
65720b57cec5SDimitry Andric ///
65730b57cec5SDimitry Andric /// See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y
65740b57cec5SDimitry Andric /// extension. In this case, LHS == Cond. (But they're not aliases.)
6575480093f4SDimitry Andric ///
6576fe6060f1SDimitry Andric /// This function also implements GCC's vector extension and the
6577fe6060f1SDimitry Andric /// OpenCL/ext_vector_type extension for conditionals. The vector extensions
6578fe6060f1SDimitry Andric /// permit the use of a?b:c where the type of a is that of a integer vector with
6579fe6060f1SDimitry Andric /// the same number of elements and size as the vectors of b and c. If one of
6580fe6060f1SDimitry Andric /// either b or c is a scalar it is implicitly converted to match the type of
6581fe6060f1SDimitry Andric /// the vector. Otherwise the expression is ill-formed. If both b and c are
6582fe6060f1SDimitry Andric /// scalars, then b and c are checked and converted to the type of a if
6583fe6060f1SDimitry Andric /// possible.
6584fe6060f1SDimitry Andric ///
6585fe6060f1SDimitry Andric /// The expressions are evaluated differently for GCC's and OpenCL's extensions.
6586fe6060f1SDimitry Andric /// For the GCC extension, the ?: operator is evaluated as
6587480093f4SDimitry Andric ///   (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]).
6588fe6060f1SDimitry Andric /// For the OpenCL extensions, the ?: operator is evaluated as
6589fe6060f1SDimitry Andric ///   (most-significant-bit-set(a[0])  ? b[0] : c[0], .. ,
6590fe6060f1SDimitry Andric ///    most-significant-bit-set(a[n]) ? b[n] : c[n]).
CXXCheckConditionalOperands(ExprResult & Cond,ExprResult & LHS,ExprResult & RHS,ExprValueKind & VK,ExprObjectKind & OK,SourceLocation QuestionLoc)65910b57cec5SDimitry Andric QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
65920b57cec5SDimitry Andric                                            ExprResult &RHS, ExprValueKind &VK,
65930b57cec5SDimitry Andric                                            ExprObjectKind &OK,
65940b57cec5SDimitry Andric                                            SourceLocation QuestionLoc) {
6595480093f4SDimitry Andric   // FIXME: Handle C99's complex types, block pointers and Obj-C++ interface
6596480093f4SDimitry Andric   // pointers.
65970b57cec5SDimitry Andric 
65980b57cec5SDimitry Andric   // Assume r-value.
6599fe6060f1SDimitry Andric   VK = VK_PRValue;
66000b57cec5SDimitry Andric   OK = OK_Ordinary;
6601480093f4SDimitry Andric   bool IsVectorConditional =
6602480093f4SDimitry Andric       isValidVectorForConditionalCondition(Context, Cond.get()->getType());
6603480093f4SDimitry Andric 
660481ad6265SDimitry Andric   bool IsSizelessVectorConditional =
660581ad6265SDimitry Andric       isValidSizelessVectorForConditionalCondition(Context,
660681ad6265SDimitry Andric                                                    Cond.get()->getType());
660781ad6265SDimitry Andric 
6608480093f4SDimitry Andric   // C++11 [expr.cond]p1
6609480093f4SDimitry Andric   //   The first expression is contextually converted to bool.
6610480093f4SDimitry Andric   if (!Cond.get()->isTypeDependent()) {
661181ad6265SDimitry Andric     ExprResult CondRes = IsVectorConditional || IsSizelessVectorConditional
6612480093f4SDimitry Andric                              ? DefaultFunctionArrayLvalueConversion(Cond.get())
6613480093f4SDimitry Andric                              : CheckCXXBooleanCondition(Cond.get());
6614480093f4SDimitry Andric     if (CondRes.isInvalid())
6615480093f4SDimitry Andric       return QualType();
6616480093f4SDimitry Andric     Cond = CondRes;
6617480093f4SDimitry Andric   } else {
6618480093f4SDimitry Andric     // To implement C++, the first expression typically doesn't alter the result
6619480093f4SDimitry Andric     // type of the conditional, however the GCC compatible vector extension
6620480093f4SDimitry Andric     // changes the result type to be that of the conditional. Since we cannot
6621480093f4SDimitry Andric     // know if this is a vector extension here, delay the conversion of the
6622480093f4SDimitry Andric     // LHS/RHS below until later.
6623480093f4SDimitry Andric     return Context.DependentTy;
6624480093f4SDimitry Andric   }
6625480093f4SDimitry Andric 
66260b57cec5SDimitry Andric 
66270b57cec5SDimitry Andric   // Either of the arguments dependent?
66280b57cec5SDimitry Andric   if (LHS.get()->isTypeDependent() || RHS.get()->isTypeDependent())
66290b57cec5SDimitry Andric     return Context.DependentTy;
66300b57cec5SDimitry Andric 
66310b57cec5SDimitry Andric   // C++11 [expr.cond]p2
66320b57cec5SDimitry Andric   //   If either the second or the third operand has type (cv) void, ...
66330b57cec5SDimitry Andric   QualType LTy = LHS.get()->getType();
66340b57cec5SDimitry Andric   QualType RTy = RHS.get()->getType();
66350b57cec5SDimitry Andric   bool LVoid = LTy->isVoidType();
66360b57cec5SDimitry Andric   bool RVoid = RTy->isVoidType();
66370b57cec5SDimitry Andric   if (LVoid || RVoid) {
66380b57cec5SDimitry Andric     //   ... one of the following shall hold:
66390b57cec5SDimitry Andric     //   -- The second or the third operand (but not both) is a (possibly
66400b57cec5SDimitry Andric     //      parenthesized) throw-expression; the result is of the type
66410b57cec5SDimitry Andric     //      and value category of the other.
66420b57cec5SDimitry Andric     bool LThrow = isa<CXXThrowExpr>(LHS.get()->IgnoreParenImpCasts());
66430b57cec5SDimitry Andric     bool RThrow = isa<CXXThrowExpr>(RHS.get()->IgnoreParenImpCasts());
6644480093f4SDimitry Andric 
6645480093f4SDimitry Andric     // Void expressions aren't legal in the vector-conditional expressions.
6646480093f4SDimitry Andric     if (IsVectorConditional) {
6647480093f4SDimitry Andric       SourceRange DiagLoc =
6648480093f4SDimitry Andric           LVoid ? LHS.get()->getSourceRange() : RHS.get()->getSourceRange();
6649480093f4SDimitry Andric       bool IsThrow = LVoid ? LThrow : RThrow;
6650480093f4SDimitry Andric       Diag(DiagLoc.getBegin(), diag::err_conditional_vector_has_void)
6651480093f4SDimitry Andric           << DiagLoc << IsThrow;
6652480093f4SDimitry Andric       return QualType();
6653480093f4SDimitry Andric     }
6654480093f4SDimitry Andric 
66550b57cec5SDimitry Andric     if (LThrow != RThrow) {
66560b57cec5SDimitry Andric       Expr *NonThrow = LThrow ? RHS.get() : LHS.get();
66570b57cec5SDimitry Andric       VK = NonThrow->getValueKind();
66580b57cec5SDimitry Andric       // DR (no number yet): the result is a bit-field if the
66590b57cec5SDimitry Andric       // non-throw-expression operand is a bit-field.
66600b57cec5SDimitry Andric       OK = NonThrow->getObjectKind();
66610b57cec5SDimitry Andric       return NonThrow->getType();
66620b57cec5SDimitry Andric     }
66630b57cec5SDimitry Andric 
66640b57cec5SDimitry Andric     //   -- Both the second and third operands have type void; the result is of
66650b57cec5SDimitry Andric     //      type void and is a prvalue.
66660b57cec5SDimitry Andric     if (LVoid && RVoid)
6667bdd1243dSDimitry Andric       return Context.getCommonSugaredType(LTy, RTy);
66680b57cec5SDimitry Andric 
66690b57cec5SDimitry Andric     // Neither holds, error.
66700b57cec5SDimitry Andric     Diag(QuestionLoc, diag::err_conditional_void_nonvoid)
66710b57cec5SDimitry Andric       << (LVoid ? RTy : LTy) << (LVoid ? 0 : 1)
66720b57cec5SDimitry Andric       << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
66730b57cec5SDimitry Andric     return QualType();
66740b57cec5SDimitry Andric   }
66750b57cec5SDimitry Andric 
66760b57cec5SDimitry Andric   // Neither is void.
6677480093f4SDimitry Andric   if (IsVectorConditional)
6678fe6060f1SDimitry Andric     return CheckVectorConditionalTypes(Cond, LHS, RHS, QuestionLoc);
66790b57cec5SDimitry Andric 
668081ad6265SDimitry Andric   if (IsSizelessVectorConditional)
668181ad6265SDimitry Andric     return CheckSizelessVectorConditionalTypes(Cond, LHS, RHS, QuestionLoc);
668281ad6265SDimitry Andric 
668306c3fb27SDimitry Andric   // WebAssembly tables are not allowed as conditional LHS or RHS.
668406c3fb27SDimitry Andric   if (LTy->isWebAssemblyTableType() || RTy->isWebAssemblyTableType()) {
668506c3fb27SDimitry Andric     Diag(QuestionLoc, diag::err_wasm_table_conditional_expression)
668606c3fb27SDimitry Andric         << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
668706c3fb27SDimitry Andric     return QualType();
668806c3fb27SDimitry Andric   }
668906c3fb27SDimitry Andric 
66900b57cec5SDimitry Andric   // C++11 [expr.cond]p3
66910b57cec5SDimitry Andric   //   Otherwise, if the second and third operand have different types, and
66920b57cec5SDimitry Andric   //   either has (cv) class type [...] an attempt is made to convert each of
66930b57cec5SDimitry Andric   //   those operands to the type of the other.
66940b57cec5SDimitry Andric   if (!Context.hasSameType(LTy, RTy) &&
66950b57cec5SDimitry Andric       (LTy->isRecordType() || RTy->isRecordType())) {
66960b57cec5SDimitry Andric     // These return true if a single direction is already ambiguous.
66970b57cec5SDimitry Andric     QualType L2RType, R2LType;
66980b57cec5SDimitry Andric     bool HaveL2R, HaveR2L;
66990b57cec5SDimitry Andric     if (TryClassUnification(*this, LHS.get(), RHS.get(), QuestionLoc, HaveL2R, L2RType))
67000b57cec5SDimitry Andric       return QualType();
67010b57cec5SDimitry Andric     if (TryClassUnification(*this, RHS.get(), LHS.get(), QuestionLoc, HaveR2L, R2LType))
67020b57cec5SDimitry Andric       return QualType();
67030b57cec5SDimitry Andric 
67040b57cec5SDimitry Andric     //   If both can be converted, [...] the program is ill-formed.
67050b57cec5SDimitry Andric     if (HaveL2R && HaveR2L) {
67060b57cec5SDimitry Andric       Diag(QuestionLoc, diag::err_conditional_ambiguous)
67070b57cec5SDimitry Andric         << LTy << RTy << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
67080b57cec5SDimitry Andric       return QualType();
67090b57cec5SDimitry Andric     }
67100b57cec5SDimitry Andric 
67110b57cec5SDimitry Andric     //   If exactly one conversion is possible, that conversion is applied to
67120b57cec5SDimitry Andric     //   the chosen operand and the converted operands are used in place of the
67130b57cec5SDimitry Andric     //   original operands for the remainder of this section.
67140b57cec5SDimitry Andric     if (HaveL2R) {
67150b57cec5SDimitry Andric       if (ConvertForConditional(*this, LHS, L2RType) || LHS.isInvalid())
67160b57cec5SDimitry Andric         return QualType();
67170b57cec5SDimitry Andric       LTy = LHS.get()->getType();
67180b57cec5SDimitry Andric     } else if (HaveR2L) {
67190b57cec5SDimitry Andric       if (ConvertForConditional(*this, RHS, R2LType) || RHS.isInvalid())
67200b57cec5SDimitry Andric         return QualType();
67210b57cec5SDimitry Andric       RTy = RHS.get()->getType();
67220b57cec5SDimitry Andric     }
67230b57cec5SDimitry Andric   }
67240b57cec5SDimitry Andric 
67250b57cec5SDimitry Andric   // C++11 [expr.cond]p3
67260b57cec5SDimitry Andric   //   if both are glvalues of the same value category and the same type except
67270b57cec5SDimitry Andric   //   for cv-qualification, an attempt is made to convert each of those
67280b57cec5SDimitry Andric   //   operands to the type of the other.
67290b57cec5SDimitry Andric   // FIXME:
67300b57cec5SDimitry Andric   //   Resolving a defect in P0012R1: we extend this to cover all cases where
67310b57cec5SDimitry Andric   //   one of the operands is reference-compatible with the other, in order
6732480093f4SDimitry Andric   //   to support conditionals between functions differing in noexcept. This
6733480093f4SDimitry Andric   //   will similarly cover difference in array bounds after P0388R4.
6734480093f4SDimitry Andric   // FIXME: If LTy and RTy have a composite pointer type, should we convert to
6735480093f4SDimitry Andric   //   that instead?
67360b57cec5SDimitry Andric   ExprValueKind LVK = LHS.get()->getValueKind();
67370b57cec5SDimitry Andric   ExprValueKind RVK = RHS.get()->getValueKind();
6738fe6060f1SDimitry Andric   if (!Context.hasSameType(LTy, RTy) && LVK == RVK && LVK != VK_PRValue) {
67390b57cec5SDimitry Andric     // DerivedToBase was already handled by the class-specific case above.
67400b57cec5SDimitry Andric     // FIXME: Should we allow ObjC conversions here?
6741480093f4SDimitry Andric     const ReferenceConversions AllowedConversions =
6742480093f4SDimitry Andric         ReferenceConversions::Qualification |
6743480093f4SDimitry Andric         ReferenceConversions::NestedQualification |
6744480093f4SDimitry Andric         ReferenceConversions::Function;
6745480093f4SDimitry Andric 
6746480093f4SDimitry Andric     ReferenceConversions RefConv;
6747480093f4SDimitry Andric     if (CompareReferenceRelationship(QuestionLoc, LTy, RTy, &RefConv) ==
6748480093f4SDimitry Andric             Ref_Compatible &&
6749480093f4SDimitry Andric         !(RefConv & ~AllowedConversions) &&
67500b57cec5SDimitry Andric         // [...] subject to the constraint that the reference must bind
67510b57cec5SDimitry Andric         // directly [...]
6752a7dea167SDimitry Andric         !RHS.get()->refersToBitField() && !RHS.get()->refersToVectorElement()) {
67530b57cec5SDimitry Andric       RHS = ImpCastExprToType(RHS.get(), LTy, CK_NoOp, RVK);
67540b57cec5SDimitry Andric       RTy = RHS.get()->getType();
6755480093f4SDimitry Andric     } else if (CompareReferenceRelationship(QuestionLoc, RTy, LTy, &RefConv) ==
6756480093f4SDimitry Andric                    Ref_Compatible &&
6757480093f4SDimitry Andric                !(RefConv & ~AllowedConversions) &&
67580b57cec5SDimitry Andric                !LHS.get()->refersToBitField() &&
67590b57cec5SDimitry Andric                !LHS.get()->refersToVectorElement()) {
67600b57cec5SDimitry Andric       LHS = ImpCastExprToType(LHS.get(), RTy, CK_NoOp, LVK);
67610b57cec5SDimitry Andric       LTy = LHS.get()->getType();
67620b57cec5SDimitry Andric     }
67630b57cec5SDimitry Andric   }
67640b57cec5SDimitry Andric 
67650b57cec5SDimitry Andric   // C++11 [expr.cond]p4
67660b57cec5SDimitry Andric   //   If the second and third operands are glvalues of the same value
67670b57cec5SDimitry Andric   //   category and have the same type, the result is of that type and
67680b57cec5SDimitry Andric   //   value category and it is a bit-field if the second or the third
67690b57cec5SDimitry Andric   //   operand is a bit-field, or if both are bit-fields.
67700b57cec5SDimitry Andric   // We only extend this to bitfields, not to the crazy other kinds of
67710b57cec5SDimitry Andric   // l-values.
67720b57cec5SDimitry Andric   bool Same = Context.hasSameType(LTy, RTy);
6773fe6060f1SDimitry Andric   if (Same && LVK == RVK && LVK != VK_PRValue &&
67740b57cec5SDimitry Andric       LHS.get()->isOrdinaryOrBitFieldObject() &&
67750b57cec5SDimitry Andric       RHS.get()->isOrdinaryOrBitFieldObject()) {
67760b57cec5SDimitry Andric     VK = LHS.get()->getValueKind();
67770b57cec5SDimitry Andric     if (LHS.get()->getObjectKind() == OK_BitField ||
67780b57cec5SDimitry Andric         RHS.get()->getObjectKind() == OK_BitField)
67790b57cec5SDimitry Andric       OK = OK_BitField;
6780bdd1243dSDimitry Andric     return Context.getCommonSugaredType(LTy, RTy);
67810b57cec5SDimitry Andric   }
67820b57cec5SDimitry Andric 
67830b57cec5SDimitry Andric   // C++11 [expr.cond]p5
67840b57cec5SDimitry Andric   //   Otherwise, the result is a prvalue. If the second and third operands
67850b57cec5SDimitry Andric   //   do not have the same type, and either has (cv) class type, ...
67860b57cec5SDimitry Andric   if (!Same && (LTy->isRecordType() || RTy->isRecordType())) {
67870b57cec5SDimitry Andric     //   ... overload resolution is used to determine the conversions (if any)
67880b57cec5SDimitry Andric     //   to be applied to the operands. If the overload resolution fails, the
67890b57cec5SDimitry Andric     //   program is ill-formed.
67900b57cec5SDimitry Andric     if (FindConditionalOverload(*this, LHS, RHS, QuestionLoc))
67910b57cec5SDimitry Andric       return QualType();
67920b57cec5SDimitry Andric   }
67930b57cec5SDimitry Andric 
67940b57cec5SDimitry Andric   // C++11 [expr.cond]p6
67950b57cec5SDimitry Andric   //   Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard
67960b57cec5SDimitry Andric   //   conversions are performed on the second and third operands.
67970b57cec5SDimitry Andric   LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
67980b57cec5SDimitry Andric   RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
67990b57cec5SDimitry Andric   if (LHS.isInvalid() || RHS.isInvalid())
68000b57cec5SDimitry Andric     return QualType();
68010b57cec5SDimitry Andric   LTy = LHS.get()->getType();
68020b57cec5SDimitry Andric   RTy = RHS.get()->getType();
68030b57cec5SDimitry Andric 
68040b57cec5SDimitry Andric   //   After those conversions, one of the following shall hold:
68050b57cec5SDimitry Andric   //   -- The second and third operands have the same type; the result
68060b57cec5SDimitry Andric   //      is of that type. If the operands have class type, the result
68070b57cec5SDimitry Andric   //      is a prvalue temporary of the result type, which is
68080b57cec5SDimitry Andric   //      copy-initialized from either the second operand or the third
68090b57cec5SDimitry Andric   //      operand depending on the value of the first operand.
6810bdd1243dSDimitry Andric   if (Context.hasSameType(LTy, RTy)) {
68110b57cec5SDimitry Andric     if (LTy->isRecordType()) {
68120b57cec5SDimitry Andric       // The operands have class type. Make a temporary copy.
6813bdd1243dSDimitry Andric       ExprResult LHSCopy = PerformCopyInitialization(
6814bdd1243dSDimitry Andric           InitializedEntity::InitializeTemporary(LTy), SourceLocation(), LHS);
68150b57cec5SDimitry Andric       if (LHSCopy.isInvalid())
68160b57cec5SDimitry Andric         return QualType();
68170b57cec5SDimitry Andric 
6818bdd1243dSDimitry Andric       ExprResult RHSCopy = PerformCopyInitialization(
6819bdd1243dSDimitry Andric           InitializedEntity::InitializeTemporary(RTy), SourceLocation(), RHS);
68200b57cec5SDimitry Andric       if (RHSCopy.isInvalid())
68210b57cec5SDimitry Andric         return QualType();
68220b57cec5SDimitry Andric 
68230b57cec5SDimitry Andric       LHS = LHSCopy;
68240b57cec5SDimitry Andric       RHS = RHSCopy;
68250b57cec5SDimitry Andric     }
6826bdd1243dSDimitry Andric     return Context.getCommonSugaredType(LTy, RTy);
68270b57cec5SDimitry Andric   }
68280b57cec5SDimitry Andric 
68290b57cec5SDimitry Andric   // Extension: conditional operator involving vector types.
68300b57cec5SDimitry Andric   if (LTy->isVectorType() || RTy->isVectorType())
68310b57cec5SDimitry Andric     return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/ false,
68320b57cec5SDimitry Andric                                /*AllowBothBool*/ true,
683381ad6265SDimitry Andric                                /*AllowBoolConversions*/ false,
683481ad6265SDimitry Andric                                /*AllowBoolOperation*/ false,
683581ad6265SDimitry Andric                                /*ReportInvalid*/ true);
68360b57cec5SDimitry Andric 
68370b57cec5SDimitry Andric   //   -- The second and third operands have arithmetic or enumeration type;
68380b57cec5SDimitry Andric   //      the usual arithmetic conversions are performed to bring them to a
68390b57cec5SDimitry Andric   //      common type, and the result is of that type.
68400b57cec5SDimitry Andric   if (LTy->isArithmeticType() && RTy->isArithmeticType()) {
6841480093f4SDimitry Andric     QualType ResTy =
6842480093f4SDimitry Andric         UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional);
68430b57cec5SDimitry Andric     if (LHS.isInvalid() || RHS.isInvalid())
68440b57cec5SDimitry Andric       return QualType();
68450b57cec5SDimitry Andric     if (ResTy.isNull()) {
68460b57cec5SDimitry Andric       Diag(QuestionLoc,
68470b57cec5SDimitry Andric            diag::err_typecheck_cond_incompatible_operands) << LTy << RTy
68480b57cec5SDimitry Andric         << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
68490b57cec5SDimitry Andric       return QualType();
68500b57cec5SDimitry Andric     }
68510b57cec5SDimitry Andric 
68520b57cec5SDimitry Andric     LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy));
68530b57cec5SDimitry Andric     RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy));
68540b57cec5SDimitry Andric 
68550b57cec5SDimitry Andric     return ResTy;
68560b57cec5SDimitry Andric   }
68570b57cec5SDimitry Andric 
68580b57cec5SDimitry Andric   //   -- The second and third operands have pointer type, or one has pointer
68590b57cec5SDimitry Andric   //      type and the other is a null pointer constant, or both are null
68600b57cec5SDimitry Andric   //      pointer constants, at least one of which is non-integral; pointer
68610b57cec5SDimitry Andric   //      conversions and qualification conversions are performed to bring them
68620b57cec5SDimitry Andric   //      to their composite pointer type. The result is of the composite
68630b57cec5SDimitry Andric   //      pointer type.
68640b57cec5SDimitry Andric   //   -- The second and third operands have pointer to member type, or one has
68650b57cec5SDimitry Andric   //      pointer to member type and the other is a null pointer constant;
68660b57cec5SDimitry Andric   //      pointer to member conversions and qualification conversions are
68670b57cec5SDimitry Andric   //      performed to bring them to a common type, whose cv-qualification
68680b57cec5SDimitry Andric   //      shall match the cv-qualification of either the second or the third
68690b57cec5SDimitry Andric   //      operand. The result is of the common type.
68700b57cec5SDimitry Andric   QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS);
68710b57cec5SDimitry Andric   if (!Composite.isNull())
68720b57cec5SDimitry Andric     return Composite;
68730b57cec5SDimitry Andric 
68740b57cec5SDimitry Andric   // Similarly, attempt to find composite type of two objective-c pointers.
68750b57cec5SDimitry Andric   Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc);
6876e8d8bef9SDimitry Andric   if (LHS.isInvalid() || RHS.isInvalid())
6877e8d8bef9SDimitry Andric     return QualType();
68780b57cec5SDimitry Andric   if (!Composite.isNull())
68790b57cec5SDimitry Andric     return Composite;
68800b57cec5SDimitry Andric 
68810b57cec5SDimitry Andric   // Check if we are using a null with a non-pointer type.
68820b57cec5SDimitry Andric   if (DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc))
68830b57cec5SDimitry Andric     return QualType();
68840b57cec5SDimitry Andric 
68850b57cec5SDimitry Andric   Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
68860b57cec5SDimitry Andric     << LHS.get()->getType() << RHS.get()->getType()
68870b57cec5SDimitry Andric     << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
68880b57cec5SDimitry Andric   return QualType();
68890b57cec5SDimitry Andric }
68900b57cec5SDimitry Andric 
68910b57cec5SDimitry Andric /// Find a merged pointer type and convert the two expressions to it.
68920b57cec5SDimitry Andric ///
6893480093f4SDimitry Andric /// This finds the composite pointer type for \p E1 and \p E2 according to
6894480093f4SDimitry Andric /// C++2a [expr.type]p3. It converts both expressions to this type and returns
6895480093f4SDimitry Andric /// it.  It does not emit diagnostics (FIXME: that's not true if \p ConvertArgs
6896480093f4SDimitry Andric /// is \c true).
68970b57cec5SDimitry Andric ///
68980b57cec5SDimitry Andric /// \param Loc The location of the operator requiring these two expressions to
68990b57cec5SDimitry Andric /// be converted to the composite pointer type.
69000b57cec5SDimitry Andric ///
69010b57cec5SDimitry Andric /// \param ConvertArgs If \c false, do not convert E1 and E2 to the target type.
FindCompositePointerType(SourceLocation Loc,Expr * & E1,Expr * & E2,bool ConvertArgs)69020b57cec5SDimitry Andric QualType Sema::FindCompositePointerType(SourceLocation Loc,
69030b57cec5SDimitry Andric                                         Expr *&E1, Expr *&E2,
69040b57cec5SDimitry Andric                                         bool ConvertArgs) {
69050b57cec5SDimitry Andric   assert(getLangOpts().CPlusPlus && "This function assumes C++");
69060b57cec5SDimitry Andric 
69070b57cec5SDimitry Andric   // C++1z [expr]p14:
69080b57cec5SDimitry Andric   //   The composite pointer type of two operands p1 and p2 having types T1
69090b57cec5SDimitry Andric   //   and T2
69100b57cec5SDimitry Andric   QualType T1 = E1->getType(), T2 = E2->getType();
69110b57cec5SDimitry Andric 
69120b57cec5SDimitry Andric   //   where at least one is a pointer or pointer to member type or
69130b57cec5SDimitry Andric   //   std::nullptr_t is:
69140b57cec5SDimitry Andric   bool T1IsPointerLike = T1->isAnyPointerType() || T1->isMemberPointerType() ||
69150b57cec5SDimitry Andric                          T1->isNullPtrType();
69160b57cec5SDimitry Andric   bool T2IsPointerLike = T2->isAnyPointerType() || T2->isMemberPointerType() ||
69170b57cec5SDimitry Andric                          T2->isNullPtrType();
69180b57cec5SDimitry Andric   if (!T1IsPointerLike && !T2IsPointerLike)
69190b57cec5SDimitry Andric     return QualType();
69200b57cec5SDimitry Andric 
69210b57cec5SDimitry Andric   //   - if both p1 and p2 are null pointer constants, std::nullptr_t;
69220b57cec5SDimitry Andric   // This can't actually happen, following the standard, but we also use this
69230b57cec5SDimitry Andric   // to implement the end of [expr.conv], which hits this case.
69240b57cec5SDimitry Andric   //
69250b57cec5SDimitry Andric   //   - if either p1 or p2 is a null pointer constant, T2 or T1, respectively;
69260b57cec5SDimitry Andric   if (T1IsPointerLike &&
69270b57cec5SDimitry Andric       E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
69280b57cec5SDimitry Andric     if (ConvertArgs)
69290b57cec5SDimitry Andric       E2 = ImpCastExprToType(E2, T1, T1->isMemberPointerType()
69300b57cec5SDimitry Andric                                          ? CK_NullToMemberPointer
69310b57cec5SDimitry Andric                                          : CK_NullToPointer).get();
69320b57cec5SDimitry Andric     return T1;
69330b57cec5SDimitry Andric   }
69340b57cec5SDimitry Andric   if (T2IsPointerLike &&
69350b57cec5SDimitry Andric       E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
69360b57cec5SDimitry Andric     if (ConvertArgs)
69370b57cec5SDimitry Andric       E1 = ImpCastExprToType(E1, T2, T2->isMemberPointerType()
69380b57cec5SDimitry Andric                                          ? CK_NullToMemberPointer
69390b57cec5SDimitry Andric                                          : CK_NullToPointer).get();
69400b57cec5SDimitry Andric     return T2;
69410b57cec5SDimitry Andric   }
69420b57cec5SDimitry Andric 
69430b57cec5SDimitry Andric   // Now both have to be pointers or member pointers.
69440b57cec5SDimitry Andric   if (!T1IsPointerLike || !T2IsPointerLike)
69450b57cec5SDimitry Andric     return QualType();
69460b57cec5SDimitry Andric   assert(!T1->isNullPtrType() && !T2->isNullPtrType() &&
69470b57cec5SDimitry Andric          "nullptr_t should be a null pointer constant");
69480b57cec5SDimitry Andric 
6949480093f4SDimitry Andric   struct Step {
6950480093f4SDimitry Andric     enum Kind { Pointer, ObjCPointer, MemberPointer, Array } K;
6951480093f4SDimitry Andric     // Qualifiers to apply under the step kind.
6952480093f4SDimitry Andric     Qualifiers Quals;
6953480093f4SDimitry Andric     /// The class for a pointer-to-member; a constant array type with a bound
6954480093f4SDimitry Andric     /// (if any) for an array.
6955480093f4SDimitry Andric     const Type *ClassOrBound;
6956480093f4SDimitry Andric 
6957480093f4SDimitry Andric     Step(Kind K, const Type *ClassOrBound = nullptr)
695804eeddc0SDimitry Andric         : K(K), ClassOrBound(ClassOrBound) {}
6959480093f4SDimitry Andric     QualType rebuild(ASTContext &Ctx, QualType T) const {
6960480093f4SDimitry Andric       T = Ctx.getQualifiedType(T, Quals);
6961480093f4SDimitry Andric       switch (K) {
6962480093f4SDimitry Andric       case Pointer:
6963480093f4SDimitry Andric         return Ctx.getPointerType(T);
6964480093f4SDimitry Andric       case MemberPointer:
6965480093f4SDimitry Andric         return Ctx.getMemberPointerType(T, ClassOrBound);
6966480093f4SDimitry Andric       case ObjCPointer:
6967480093f4SDimitry Andric         return Ctx.getObjCObjectPointerType(T);
6968480093f4SDimitry Andric       case Array:
6969480093f4SDimitry Andric         if (auto *CAT = cast_or_null<ConstantArrayType>(ClassOrBound))
6970480093f4SDimitry Andric           return Ctx.getConstantArrayType(T, CAT->getSize(), nullptr,
69715f757f3fSDimitry Andric                                           ArraySizeModifier::Normal, 0);
6972480093f4SDimitry Andric         else
69735f757f3fSDimitry Andric           return Ctx.getIncompleteArrayType(T, ArraySizeModifier::Normal, 0);
6974480093f4SDimitry Andric       }
6975480093f4SDimitry Andric       llvm_unreachable("unknown step kind");
6976480093f4SDimitry Andric     }
6977480093f4SDimitry Andric   };
6978480093f4SDimitry Andric 
6979480093f4SDimitry Andric   SmallVector<Step, 8> Steps;
6980480093f4SDimitry Andric 
69810b57cec5SDimitry Andric   //  - if T1 is "pointer to cv1 C1" and T2 is "pointer to cv2 C2", where C1
69820b57cec5SDimitry Andric   //    is reference-related to C2 or C2 is reference-related to C1 (8.6.3),
69830b57cec5SDimitry Andric   //    the cv-combined type of T1 and T2 or the cv-combined type of T2 and T1,
69840b57cec5SDimitry Andric   //    respectively;
69850b57cec5SDimitry Andric   //  - if T1 is "pointer to member of C1 of type cv1 U1" and T2 is "pointer
6986480093f4SDimitry Andric   //    to member of C2 of type cv2 U2" for some non-function type U, where
6987480093f4SDimitry Andric   //    C1 is reference-related to C2 or C2 is reference-related to C1, the
6988480093f4SDimitry Andric   //    cv-combined type of T2 and T1 or the cv-combined type of T1 and T2,
6989480093f4SDimitry Andric   //    respectively;
69900b57cec5SDimitry Andric   //  - if T1 and T2 are similar types (4.5), the cv-combined type of T1 and
69910b57cec5SDimitry Andric   //    T2;
69920b57cec5SDimitry Andric   //
6993480093f4SDimitry Andric   // Dismantle T1 and T2 to simultaneously determine whether they are similar
6994480093f4SDimitry Andric   // and to prepare to form the cv-combined type if so.
69950b57cec5SDimitry Andric   QualType Composite1 = T1;
69960b57cec5SDimitry Andric   QualType Composite2 = T2;
69970b57cec5SDimitry Andric   unsigned NeedConstBefore = 0;
69980b57cec5SDimitry Andric   while (true) {
6999480093f4SDimitry Andric     assert(!Composite1.isNull() && !Composite2.isNull());
7000480093f4SDimitry Andric 
7001480093f4SDimitry Andric     Qualifiers Q1, Q2;
7002480093f4SDimitry Andric     Composite1 = Context.getUnqualifiedArrayType(Composite1, Q1);
7003480093f4SDimitry Andric     Composite2 = Context.getUnqualifiedArrayType(Composite2, Q2);
7004480093f4SDimitry Andric 
7005480093f4SDimitry Andric     // Top-level qualifiers are ignored. Merge at all lower levels.
7006480093f4SDimitry Andric     if (!Steps.empty()) {
7007480093f4SDimitry Andric       // Find the qualifier union: (approximately) the unique minimal set of
7008480093f4SDimitry Andric       // qualifiers that is compatible with both types.
7009480093f4SDimitry Andric       Qualifiers Quals = Qualifiers::fromCVRUMask(Q1.getCVRUQualifiers() |
7010480093f4SDimitry Andric                                                   Q2.getCVRUQualifiers());
7011480093f4SDimitry Andric 
7012480093f4SDimitry Andric       // Under one level of pointer or pointer-to-member, we can change to an
7013480093f4SDimitry Andric       // unambiguous compatible address space.
7014480093f4SDimitry Andric       if (Q1.getAddressSpace() == Q2.getAddressSpace()) {
7015480093f4SDimitry Andric         Quals.setAddressSpace(Q1.getAddressSpace());
7016480093f4SDimitry Andric       } else if (Steps.size() == 1) {
7017480093f4SDimitry Andric         bool MaybeQ1 = Q1.isAddressSpaceSupersetOf(Q2);
7018480093f4SDimitry Andric         bool MaybeQ2 = Q2.isAddressSpaceSupersetOf(Q1);
7019349cc55cSDimitry Andric         if (MaybeQ1 == MaybeQ2) {
7020349cc55cSDimitry Andric           // Exception for ptr size address spaces. Should be able to choose
7021349cc55cSDimitry Andric           // either address space during comparison.
7022349cc55cSDimitry Andric           if (isPtrSizeAddressSpace(Q1.getAddressSpace()) ||
7023349cc55cSDimitry Andric               isPtrSizeAddressSpace(Q2.getAddressSpace()))
7024349cc55cSDimitry Andric             MaybeQ1 = true;
7025349cc55cSDimitry Andric           else
7026480093f4SDimitry Andric             return QualType(); // No unique best address space.
7027349cc55cSDimitry Andric         }
7028480093f4SDimitry Andric         Quals.setAddressSpace(MaybeQ1 ? Q1.getAddressSpace()
7029480093f4SDimitry Andric                                       : Q2.getAddressSpace());
7030480093f4SDimitry Andric       } else {
7031480093f4SDimitry Andric         return QualType();
7032480093f4SDimitry Andric       }
7033480093f4SDimitry Andric 
7034480093f4SDimitry Andric       // FIXME: In C, we merge __strong and none to __strong at the top level.
7035480093f4SDimitry Andric       if (Q1.getObjCGCAttr() == Q2.getObjCGCAttr())
7036480093f4SDimitry Andric         Quals.setObjCGCAttr(Q1.getObjCGCAttr());
7037e8d8bef9SDimitry Andric       else if (T1->isVoidPointerType() || T2->isVoidPointerType())
7038e8d8bef9SDimitry Andric         assert(Steps.size() == 1);
7039480093f4SDimitry Andric       else
7040480093f4SDimitry Andric         return QualType();
7041480093f4SDimitry Andric 
7042480093f4SDimitry Andric       // Mismatched lifetime qualifiers never compatibly include each other.
7043480093f4SDimitry Andric       if (Q1.getObjCLifetime() == Q2.getObjCLifetime())
7044480093f4SDimitry Andric         Quals.setObjCLifetime(Q1.getObjCLifetime());
7045e8d8bef9SDimitry Andric       else if (T1->isVoidPointerType() || T2->isVoidPointerType())
7046e8d8bef9SDimitry Andric         assert(Steps.size() == 1);
7047480093f4SDimitry Andric       else
7048480093f4SDimitry Andric         return QualType();
7049480093f4SDimitry Andric 
7050480093f4SDimitry Andric       Steps.back().Quals = Quals;
7051480093f4SDimitry Andric       if (Q1 != Quals || Q2 != Quals)
7052480093f4SDimitry Andric         NeedConstBefore = Steps.size() - 1;
7053480093f4SDimitry Andric     }
7054480093f4SDimitry Andric 
7055480093f4SDimitry Andric     // FIXME: Can we unify the following with UnwrapSimilarTypes?
7056349cc55cSDimitry Andric 
7057349cc55cSDimitry Andric     const ArrayType *Arr1, *Arr2;
7058349cc55cSDimitry Andric     if ((Arr1 = Context.getAsArrayType(Composite1)) &&
7059349cc55cSDimitry Andric         (Arr2 = Context.getAsArrayType(Composite2))) {
7060349cc55cSDimitry Andric       auto *CAT1 = dyn_cast<ConstantArrayType>(Arr1);
7061349cc55cSDimitry Andric       auto *CAT2 = dyn_cast<ConstantArrayType>(Arr2);
7062349cc55cSDimitry Andric       if (CAT1 && CAT2 && CAT1->getSize() == CAT2->getSize()) {
7063349cc55cSDimitry Andric         Composite1 = Arr1->getElementType();
7064349cc55cSDimitry Andric         Composite2 = Arr2->getElementType();
7065349cc55cSDimitry Andric         Steps.emplace_back(Step::Array, CAT1);
7066349cc55cSDimitry Andric         continue;
7067349cc55cSDimitry Andric       }
7068349cc55cSDimitry Andric       bool IAT1 = isa<IncompleteArrayType>(Arr1);
7069349cc55cSDimitry Andric       bool IAT2 = isa<IncompleteArrayType>(Arr2);
7070349cc55cSDimitry Andric       if ((IAT1 && IAT2) ||
7071349cc55cSDimitry Andric           (getLangOpts().CPlusPlus20 && (IAT1 != IAT2) &&
7072349cc55cSDimitry Andric            ((bool)CAT1 != (bool)CAT2) &&
7073349cc55cSDimitry Andric            (Steps.empty() || Steps.back().K != Step::Array))) {
7074349cc55cSDimitry Andric         // In C++20 onwards, we can unify an array of N T with an array of
7075349cc55cSDimitry Andric         // a different or unknown bound. But we can't form an array whose
7076349cc55cSDimitry Andric         // element type is an array of unknown bound by doing so.
7077349cc55cSDimitry Andric         Composite1 = Arr1->getElementType();
7078349cc55cSDimitry Andric         Composite2 = Arr2->getElementType();
7079349cc55cSDimitry Andric         Steps.emplace_back(Step::Array);
7080349cc55cSDimitry Andric         if (CAT1 || CAT2)
7081349cc55cSDimitry Andric           NeedConstBefore = Steps.size();
7082349cc55cSDimitry Andric         continue;
7083349cc55cSDimitry Andric       }
7084349cc55cSDimitry Andric     }
7085349cc55cSDimitry Andric 
70860b57cec5SDimitry Andric     const PointerType *Ptr1, *Ptr2;
70870b57cec5SDimitry Andric     if ((Ptr1 = Composite1->getAs<PointerType>()) &&
70880b57cec5SDimitry Andric         (Ptr2 = Composite2->getAs<PointerType>())) {
70890b57cec5SDimitry Andric       Composite1 = Ptr1->getPointeeType();
70900b57cec5SDimitry Andric       Composite2 = Ptr2->getPointeeType();
7091480093f4SDimitry Andric       Steps.emplace_back(Step::Pointer);
7092480093f4SDimitry Andric       continue;
7093480093f4SDimitry Andric     }
70940b57cec5SDimitry Andric 
7095480093f4SDimitry Andric     const ObjCObjectPointerType *ObjPtr1, *ObjPtr2;
7096480093f4SDimitry Andric     if ((ObjPtr1 = Composite1->getAs<ObjCObjectPointerType>()) &&
7097480093f4SDimitry Andric         (ObjPtr2 = Composite2->getAs<ObjCObjectPointerType>())) {
7098480093f4SDimitry Andric       Composite1 = ObjPtr1->getPointeeType();
7099480093f4SDimitry Andric       Composite2 = ObjPtr2->getPointeeType();
7100480093f4SDimitry Andric       Steps.emplace_back(Step::ObjCPointer);
71010b57cec5SDimitry Andric       continue;
71020b57cec5SDimitry Andric     }
71030b57cec5SDimitry Andric 
71040b57cec5SDimitry Andric     const MemberPointerType *MemPtr1, *MemPtr2;
71050b57cec5SDimitry Andric     if ((MemPtr1 = Composite1->getAs<MemberPointerType>()) &&
71060b57cec5SDimitry Andric         (MemPtr2 = Composite2->getAs<MemberPointerType>())) {
71070b57cec5SDimitry Andric       Composite1 = MemPtr1->getPointeeType();
71080b57cec5SDimitry Andric       Composite2 = MemPtr2->getPointeeType();
71090b57cec5SDimitry Andric 
7110480093f4SDimitry Andric       // At the top level, we can perform a base-to-derived pointer-to-member
7111480093f4SDimitry Andric       // conversion:
7112480093f4SDimitry Andric       //
7113480093f4SDimitry Andric       //  - [...] where C1 is reference-related to C2 or C2 is
7114480093f4SDimitry Andric       //    reference-related to C1
7115480093f4SDimitry Andric       //
7116480093f4SDimitry Andric       // (Note that the only kinds of reference-relatedness in scope here are
7117480093f4SDimitry Andric       // "same type or derived from".) At any other level, the class must
7118480093f4SDimitry Andric       // exactly match.
7119480093f4SDimitry Andric       const Type *Class = nullptr;
7120480093f4SDimitry Andric       QualType Cls1(MemPtr1->getClass(), 0);
7121480093f4SDimitry Andric       QualType Cls2(MemPtr2->getClass(), 0);
7122480093f4SDimitry Andric       if (Context.hasSameType(Cls1, Cls2))
7123480093f4SDimitry Andric         Class = MemPtr1->getClass();
7124480093f4SDimitry Andric       else if (Steps.empty())
7125480093f4SDimitry Andric         Class = IsDerivedFrom(Loc, Cls1, Cls2) ? MemPtr1->getClass() :
7126480093f4SDimitry Andric                 IsDerivedFrom(Loc, Cls2, Cls1) ? MemPtr2->getClass() : nullptr;
7127480093f4SDimitry Andric       if (!Class)
7128480093f4SDimitry Andric         return QualType();
71290b57cec5SDimitry Andric 
7130480093f4SDimitry Andric       Steps.emplace_back(Step::MemberPointer, Class);
71310b57cec5SDimitry Andric       continue;
71320b57cec5SDimitry Andric     }
71330b57cec5SDimitry Andric 
7134480093f4SDimitry Andric     // Special case: at the top level, we can decompose an Objective-C pointer
7135480093f4SDimitry Andric     // and a 'cv void *'. Unify the qualifiers.
7136480093f4SDimitry Andric     if (Steps.empty() && ((Composite1->isVoidPointerType() &&
7137480093f4SDimitry Andric                            Composite2->isObjCObjectPointerType()) ||
7138480093f4SDimitry Andric                           (Composite1->isObjCObjectPointerType() &&
7139480093f4SDimitry Andric                            Composite2->isVoidPointerType()))) {
7140480093f4SDimitry Andric       Composite1 = Composite1->getPointeeType();
7141480093f4SDimitry Andric       Composite2 = Composite2->getPointeeType();
7142480093f4SDimitry Andric       Steps.emplace_back(Step::Pointer);
7143480093f4SDimitry Andric       continue;
7144480093f4SDimitry Andric     }
7145480093f4SDimitry Andric 
71460b57cec5SDimitry Andric     // FIXME: block pointer types?
71470b57cec5SDimitry Andric 
71480b57cec5SDimitry Andric     // Cannot unwrap any more types.
71490b57cec5SDimitry Andric     break;
71500b57cec5SDimitry Andric   }
71510b57cec5SDimitry Andric 
7152480093f4SDimitry Andric   //  - if T1 or T2 is "pointer to noexcept function" and the other type is
7153480093f4SDimitry Andric   //    "pointer to function", where the function types are otherwise the same,
7154480093f4SDimitry Andric   //    "pointer to function";
7155480093f4SDimitry Andric   //  - if T1 or T2 is "pointer to member of C1 of type function", the other
7156480093f4SDimitry Andric   //    type is "pointer to member of C2 of type noexcept function", and C1
7157480093f4SDimitry Andric   //    is reference-related to C2 or C2 is reference-related to C1, where
7158480093f4SDimitry Andric   //    the function types are otherwise the same, "pointer to member of C2 of
7159480093f4SDimitry Andric   //    type function" or "pointer to member of C1 of type function",
7160480093f4SDimitry Andric   //    respectively;
7161480093f4SDimitry Andric   //
7162480093f4SDimitry Andric   // We also support 'noreturn' here, so as a Clang extension we generalize the
7163480093f4SDimitry Andric   // above to:
7164480093f4SDimitry Andric   //
7165480093f4SDimitry Andric   //  - [Clang] If T1 and T2 are both of type "pointer to function" or
7166480093f4SDimitry Andric   //    "pointer to member function" and the pointee types can be unified
7167480093f4SDimitry Andric   //    by a function pointer conversion, that conversion is applied
7168480093f4SDimitry Andric   //    before checking the following rules.
7169480093f4SDimitry Andric   //
7170480093f4SDimitry Andric   // We've already unwrapped down to the function types, and we want to merge
7171480093f4SDimitry Andric   // rather than just convert, so do this ourselves rather than calling
71720b57cec5SDimitry Andric   // IsFunctionConversion.
71730b57cec5SDimitry Andric   //
71740b57cec5SDimitry Andric   // FIXME: In order to match the standard wording as closely as possible, we
71750b57cec5SDimitry Andric   // currently only do this under a single level of pointers. Ideally, we would
71760b57cec5SDimitry Andric   // allow this in general, and set NeedConstBefore to the relevant depth on
7177480093f4SDimitry Andric   // the side(s) where we changed anything. If we permit that, we should also
7178480093f4SDimitry Andric   // consider this conversion when determining type similarity and model it as
7179480093f4SDimitry Andric   // a qualification conversion.
7180480093f4SDimitry Andric   if (Steps.size() == 1) {
71810b57cec5SDimitry Andric     if (auto *FPT1 = Composite1->getAs<FunctionProtoType>()) {
71820b57cec5SDimitry Andric       if (auto *FPT2 = Composite2->getAs<FunctionProtoType>()) {
71830b57cec5SDimitry Andric         FunctionProtoType::ExtProtoInfo EPI1 = FPT1->getExtProtoInfo();
71840b57cec5SDimitry Andric         FunctionProtoType::ExtProtoInfo EPI2 = FPT2->getExtProtoInfo();
71850b57cec5SDimitry Andric 
71860b57cec5SDimitry Andric         // The result is noreturn if both operands are.
71870b57cec5SDimitry Andric         bool Noreturn =
71880b57cec5SDimitry Andric             EPI1.ExtInfo.getNoReturn() && EPI2.ExtInfo.getNoReturn();
71890b57cec5SDimitry Andric         EPI1.ExtInfo = EPI1.ExtInfo.withNoReturn(Noreturn);
71900b57cec5SDimitry Andric         EPI2.ExtInfo = EPI2.ExtInfo.withNoReturn(Noreturn);
71910b57cec5SDimitry Andric 
71920b57cec5SDimitry Andric         // The result is nothrow if both operands are.
71930b57cec5SDimitry Andric         SmallVector<QualType, 8> ExceptionTypeStorage;
7194bdd1243dSDimitry Andric         EPI1.ExceptionSpec = EPI2.ExceptionSpec = Context.mergeExceptionSpecs(
7195bdd1243dSDimitry Andric             EPI1.ExceptionSpec, EPI2.ExceptionSpec, ExceptionTypeStorage,
7196bdd1243dSDimitry Andric             getLangOpts().CPlusPlus17);
71970b57cec5SDimitry Andric 
71980b57cec5SDimitry Andric         Composite1 = Context.getFunctionType(FPT1->getReturnType(),
71990b57cec5SDimitry Andric                                              FPT1->getParamTypes(), EPI1);
72000b57cec5SDimitry Andric         Composite2 = Context.getFunctionType(FPT2->getReturnType(),
72010b57cec5SDimitry Andric                                              FPT2->getParamTypes(), EPI2);
72020b57cec5SDimitry Andric       }
72030b57cec5SDimitry Andric     }
72040b57cec5SDimitry Andric   }
72050b57cec5SDimitry Andric 
7206480093f4SDimitry Andric   // There are some more conversions we can perform under exactly one pointer.
7207480093f4SDimitry Andric   if (Steps.size() == 1 && Steps.front().K == Step::Pointer &&
7208480093f4SDimitry Andric       !Context.hasSameType(Composite1, Composite2)) {
7209480093f4SDimitry Andric     //  - if T1 or T2 is "pointer to cv1 void" and the other type is
7210480093f4SDimitry Andric     //    "pointer to cv2 T", where T is an object type or void,
7211480093f4SDimitry Andric     //    "pointer to cv12 void", where cv12 is the union of cv1 and cv2;
7212480093f4SDimitry Andric     if (Composite1->isVoidType() && Composite2->isObjectType())
7213480093f4SDimitry Andric       Composite2 = Composite1;
7214480093f4SDimitry Andric     else if (Composite2->isVoidType() && Composite1->isObjectType())
7215480093f4SDimitry Andric       Composite1 = Composite2;
7216480093f4SDimitry Andric     //  - if T1 is "pointer to cv1 C1" and T2 is "pointer to cv2 C2", where C1
7217480093f4SDimitry Andric     //    is reference-related to C2 or C2 is reference-related to C1 (8.6.3),
7218480093f4SDimitry Andric     //    the cv-combined type of T1 and T2 or the cv-combined type of T2 and
7219480093f4SDimitry Andric     //    T1, respectively;
7220480093f4SDimitry Andric     //
7221480093f4SDimitry Andric     // The "similar type" handling covers all of this except for the "T1 is a
7222480093f4SDimitry Andric     // base class of T2" case in the definition of reference-related.
7223480093f4SDimitry Andric     else if (IsDerivedFrom(Loc, Composite1, Composite2))
7224480093f4SDimitry Andric       Composite1 = Composite2;
7225480093f4SDimitry Andric     else if (IsDerivedFrom(Loc, Composite2, Composite1))
7226480093f4SDimitry Andric       Composite2 = Composite1;
7227480093f4SDimitry Andric   }
7228480093f4SDimitry Andric 
7229480093f4SDimitry Andric   // At this point, either the inner types are the same or we have failed to
7230480093f4SDimitry Andric   // find a composite pointer type.
7231480093f4SDimitry Andric   if (!Context.hasSameType(Composite1, Composite2))
7232480093f4SDimitry Andric     return QualType();
7233480093f4SDimitry Andric 
7234480093f4SDimitry Andric   // Per C++ [conv.qual]p3, add 'const' to every level before the last
7235480093f4SDimitry Andric   // differing qualifier.
72360b57cec5SDimitry Andric   for (unsigned I = 0; I != NeedConstBefore; ++I)
7237480093f4SDimitry Andric     Steps[I].Quals.addConst();
72380b57cec5SDimitry Andric 
7239480093f4SDimitry Andric   // Rebuild the composite type.
7240bdd1243dSDimitry Andric   QualType Composite = Context.getCommonSugaredType(Composite1, Composite2);
7241480093f4SDimitry Andric   for (auto &S : llvm::reverse(Steps))
7242480093f4SDimitry Andric     Composite = S.rebuild(Context, Composite);
72430b57cec5SDimitry Andric 
7244480093f4SDimitry Andric   if (ConvertArgs) {
7245480093f4SDimitry Andric     // Convert the expressions to the composite pointer type.
7246480093f4SDimitry Andric     InitializedEntity Entity =
7247480093f4SDimitry Andric         InitializedEntity::InitializeTemporary(Composite);
7248480093f4SDimitry Andric     InitializationKind Kind =
7249480093f4SDimitry Andric         InitializationKind::CreateCopy(Loc, SourceLocation());
72500b57cec5SDimitry Andric 
7251480093f4SDimitry Andric     InitializationSequence E1ToC(*this, Entity, Kind, E1);
7252480093f4SDimitry Andric     if (!E1ToC)
7253480093f4SDimitry Andric       return QualType();
72540b57cec5SDimitry Andric 
7255480093f4SDimitry Andric     InitializationSequence E2ToC(*this, Entity, Kind, E2);
7256480093f4SDimitry Andric     if (!E2ToC)
7257480093f4SDimitry Andric       return QualType();
7258480093f4SDimitry Andric 
7259480093f4SDimitry Andric     // FIXME: Let the caller know if these fail to avoid duplicate diagnostics.
7260480093f4SDimitry Andric     ExprResult E1Result = E1ToC.Perform(*this, Entity, Kind, E1);
72610b57cec5SDimitry Andric     if (E1Result.isInvalid())
7262480093f4SDimitry Andric       return QualType();
7263480093f4SDimitry Andric     E1 = E1Result.get();
72640b57cec5SDimitry Andric 
7265480093f4SDimitry Andric     ExprResult E2Result = E2ToC.Perform(*this, Entity, Kind, E2);
72660b57cec5SDimitry Andric     if (E2Result.isInvalid())
72670b57cec5SDimitry Andric       return QualType();
7268480093f4SDimitry Andric     E2 = E2Result.get();
72690b57cec5SDimitry Andric   }
72700b57cec5SDimitry Andric 
7271480093f4SDimitry Andric   return Composite;
72720b57cec5SDimitry Andric }
72730b57cec5SDimitry Andric 
MaybeBindToTemporary(Expr * E)72740b57cec5SDimitry Andric ExprResult Sema::MaybeBindToTemporary(Expr *E) {
72750b57cec5SDimitry Andric   if (!E)
72760b57cec5SDimitry Andric     return ExprError();
72770b57cec5SDimitry Andric 
72780b57cec5SDimitry Andric   assert(!isa<CXXBindTemporaryExpr>(E) && "Double-bound temporary?");
72790b57cec5SDimitry Andric 
72800b57cec5SDimitry Andric   // If the result is a glvalue, we shouldn't bind it.
7281fe6060f1SDimitry Andric   if (E->isGLValue())
72820b57cec5SDimitry Andric     return E;
72830b57cec5SDimitry Andric 
72840b57cec5SDimitry Andric   // In ARC, calls that return a retainable type can return retained,
72850b57cec5SDimitry Andric   // in which case we have to insert a consuming cast.
72860b57cec5SDimitry Andric   if (getLangOpts().ObjCAutoRefCount &&
72870b57cec5SDimitry Andric       E->getType()->isObjCRetainableType()) {
72880b57cec5SDimitry Andric 
72890b57cec5SDimitry Andric     bool ReturnsRetained;
72900b57cec5SDimitry Andric 
72910b57cec5SDimitry Andric     // For actual calls, we compute this by examining the type of the
72920b57cec5SDimitry Andric     // called value.
72930b57cec5SDimitry Andric     if (CallExpr *Call = dyn_cast<CallExpr>(E)) {
72940b57cec5SDimitry Andric       Expr *Callee = Call->getCallee()->IgnoreParens();
72950b57cec5SDimitry Andric       QualType T = Callee->getType();
72960b57cec5SDimitry Andric 
72970b57cec5SDimitry Andric       if (T == Context.BoundMemberTy) {
72980b57cec5SDimitry Andric         // Handle pointer-to-members.
72990b57cec5SDimitry Andric         if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Callee))
73000b57cec5SDimitry Andric           T = BinOp->getRHS()->getType();
73010b57cec5SDimitry Andric         else if (MemberExpr *Mem = dyn_cast<MemberExpr>(Callee))
73020b57cec5SDimitry Andric           T = Mem->getMemberDecl()->getType();
73030b57cec5SDimitry Andric       }
73040b57cec5SDimitry Andric 
73050b57cec5SDimitry Andric       if (const PointerType *Ptr = T->getAs<PointerType>())
73060b57cec5SDimitry Andric         T = Ptr->getPointeeType();
73070b57cec5SDimitry Andric       else if (const BlockPointerType *Ptr = T->getAs<BlockPointerType>())
73080b57cec5SDimitry Andric         T = Ptr->getPointeeType();
73090b57cec5SDimitry Andric       else if (const MemberPointerType *MemPtr = T->getAs<MemberPointerType>())
73100b57cec5SDimitry Andric         T = MemPtr->getPointeeType();
73110b57cec5SDimitry Andric 
73125ffd83dbSDimitry Andric       auto *FTy = T->castAs<FunctionType>();
73130b57cec5SDimitry Andric       ReturnsRetained = FTy->getExtInfo().getProducesResult();
73140b57cec5SDimitry Andric 
73150b57cec5SDimitry Andric     // ActOnStmtExpr arranges things so that StmtExprs of retainable
73160b57cec5SDimitry Andric     // type always produce a +1 object.
73170b57cec5SDimitry Andric     } else if (isa<StmtExpr>(E)) {
73180b57cec5SDimitry Andric       ReturnsRetained = true;
73190b57cec5SDimitry Andric 
73200b57cec5SDimitry Andric     // We hit this case with the lambda conversion-to-block optimization;
73210b57cec5SDimitry Andric     // we don't want any extra casts here.
73220b57cec5SDimitry Andric     } else if (isa<CastExpr>(E) &&
73230b57cec5SDimitry Andric                isa<BlockExpr>(cast<CastExpr>(E)->getSubExpr())) {
73240b57cec5SDimitry Andric       return E;
73250b57cec5SDimitry Andric 
73260b57cec5SDimitry Andric     // For message sends and property references, we try to find an
73270b57cec5SDimitry Andric     // actual method.  FIXME: we should infer retention by selector in
73280b57cec5SDimitry Andric     // cases where we don't have an actual method.
73290b57cec5SDimitry Andric     } else {
73300b57cec5SDimitry Andric       ObjCMethodDecl *D = nullptr;
73310b57cec5SDimitry Andric       if (ObjCMessageExpr *Send = dyn_cast<ObjCMessageExpr>(E)) {
73320b57cec5SDimitry Andric         D = Send->getMethodDecl();
73330b57cec5SDimitry Andric       } else if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(E)) {
73340b57cec5SDimitry Andric         D = BoxedExpr->getBoxingMethod();
73350b57cec5SDimitry Andric       } else if (ObjCArrayLiteral *ArrayLit = dyn_cast<ObjCArrayLiteral>(E)) {
73360b57cec5SDimitry Andric         // Don't do reclaims if we're using the zero-element array
73370b57cec5SDimitry Andric         // constant.
73380b57cec5SDimitry Andric         if (ArrayLit->getNumElements() == 0 &&
73390b57cec5SDimitry Andric             Context.getLangOpts().ObjCRuntime.hasEmptyCollections())
73400b57cec5SDimitry Andric           return E;
73410b57cec5SDimitry Andric 
73420b57cec5SDimitry Andric         D = ArrayLit->getArrayWithObjectsMethod();
73430b57cec5SDimitry Andric       } else if (ObjCDictionaryLiteral *DictLit
73440b57cec5SDimitry Andric                                         = dyn_cast<ObjCDictionaryLiteral>(E)) {
73450b57cec5SDimitry Andric         // Don't do reclaims if we're using the zero-element dictionary
73460b57cec5SDimitry Andric         // constant.
73470b57cec5SDimitry Andric         if (DictLit->getNumElements() == 0 &&
73480b57cec5SDimitry Andric             Context.getLangOpts().ObjCRuntime.hasEmptyCollections())
73490b57cec5SDimitry Andric           return E;
73500b57cec5SDimitry Andric 
73510b57cec5SDimitry Andric         D = DictLit->getDictWithObjectsMethod();
73520b57cec5SDimitry Andric       }
73530b57cec5SDimitry Andric 
73540b57cec5SDimitry Andric       ReturnsRetained = (D && D->hasAttr<NSReturnsRetainedAttr>());
73550b57cec5SDimitry Andric 
73560b57cec5SDimitry Andric       // Don't do reclaims on performSelector calls; despite their
73570b57cec5SDimitry Andric       // return type, the invoked method doesn't necessarily actually
73580b57cec5SDimitry Andric       // return an object.
73590b57cec5SDimitry Andric       if (!ReturnsRetained &&
73600b57cec5SDimitry Andric           D && D->getMethodFamily() == OMF_performSelector)
73610b57cec5SDimitry Andric         return E;
73620b57cec5SDimitry Andric     }
73630b57cec5SDimitry Andric 
73640b57cec5SDimitry Andric     // Don't reclaim an object of Class type.
73650b57cec5SDimitry Andric     if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType())
73660b57cec5SDimitry Andric       return E;
73670b57cec5SDimitry Andric 
73680b57cec5SDimitry Andric     Cleanup.setExprNeedsCleanups(true);
73690b57cec5SDimitry Andric 
73700b57cec5SDimitry Andric     CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
73710b57cec5SDimitry Andric                                    : CK_ARCReclaimReturnedObject);
73720b57cec5SDimitry Andric     return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr,
7373fe6060f1SDimitry Andric                                     VK_PRValue, FPOptionsOverride());
73740b57cec5SDimitry Andric   }
73750b57cec5SDimitry Andric 
73765ffd83dbSDimitry Andric   if (E->getType().isDestructedType() == QualType::DK_nontrivial_c_struct)
73775ffd83dbSDimitry Andric     Cleanup.setExprNeedsCleanups(true);
73785ffd83dbSDimitry Andric 
73790b57cec5SDimitry Andric   if (!getLangOpts().CPlusPlus)
73800b57cec5SDimitry Andric     return E;
73810b57cec5SDimitry Andric 
73820b57cec5SDimitry Andric   // Search for the base element type (cf. ASTContext::getBaseElementType) with
73830b57cec5SDimitry Andric   // a fast path for the common case that the type is directly a RecordType.
73840b57cec5SDimitry Andric   const Type *T = Context.getCanonicalType(E->getType().getTypePtr());
73850b57cec5SDimitry Andric   const RecordType *RT = nullptr;
73860b57cec5SDimitry Andric   while (!RT) {
73870b57cec5SDimitry Andric     switch (T->getTypeClass()) {
73880b57cec5SDimitry Andric     case Type::Record:
73890b57cec5SDimitry Andric       RT = cast<RecordType>(T);
73900b57cec5SDimitry Andric       break;
73910b57cec5SDimitry Andric     case Type::ConstantArray:
73920b57cec5SDimitry Andric     case Type::IncompleteArray:
73930b57cec5SDimitry Andric     case Type::VariableArray:
73940b57cec5SDimitry Andric     case Type::DependentSizedArray:
73950b57cec5SDimitry Andric       T = cast<ArrayType>(T)->getElementType().getTypePtr();
73960b57cec5SDimitry Andric       break;
73970b57cec5SDimitry Andric     default:
73980b57cec5SDimitry Andric       return E;
73990b57cec5SDimitry Andric     }
74000b57cec5SDimitry Andric   }
74010b57cec5SDimitry Andric 
74020b57cec5SDimitry Andric   // That should be enough to guarantee that this type is complete, if we're
74030b57cec5SDimitry Andric   // not processing a decltype expression.
74040b57cec5SDimitry Andric   CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
74050b57cec5SDimitry Andric   if (RD->isInvalidDecl() || RD->isDependentContext())
74060b57cec5SDimitry Andric     return E;
74070b57cec5SDimitry Andric 
74080b57cec5SDimitry Andric   bool IsDecltype = ExprEvalContexts.back().ExprContext ==
74090b57cec5SDimitry Andric                     ExpressionEvaluationContextRecord::EK_Decltype;
74100b57cec5SDimitry Andric   CXXDestructorDecl *Destructor = IsDecltype ? nullptr : LookupDestructor(RD);
74110b57cec5SDimitry Andric 
74120b57cec5SDimitry Andric   if (Destructor) {
74130b57cec5SDimitry Andric     MarkFunctionReferenced(E->getExprLoc(), Destructor);
74140b57cec5SDimitry Andric     CheckDestructorAccess(E->getExprLoc(), Destructor,
74150b57cec5SDimitry Andric                           PDiag(diag::err_access_dtor_temp)
74160b57cec5SDimitry Andric                             << E->getType());
74170b57cec5SDimitry Andric     if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
74180b57cec5SDimitry Andric       return ExprError();
74190b57cec5SDimitry Andric 
74200b57cec5SDimitry Andric     // If destructor is trivial, we can avoid the extra copy.
74210b57cec5SDimitry Andric     if (Destructor->isTrivial())
74220b57cec5SDimitry Andric       return E;
74230b57cec5SDimitry Andric 
74240b57cec5SDimitry Andric     // We need a cleanup, but we don't need to remember the temporary.
74250b57cec5SDimitry Andric     Cleanup.setExprNeedsCleanups(true);
74260b57cec5SDimitry Andric   }
74270b57cec5SDimitry Andric 
74280b57cec5SDimitry Andric   CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor);
74290b57cec5SDimitry Andric   CXXBindTemporaryExpr *Bind = CXXBindTemporaryExpr::Create(Context, Temp, E);
74300b57cec5SDimitry Andric 
74310b57cec5SDimitry Andric   if (IsDecltype)
74320b57cec5SDimitry Andric     ExprEvalContexts.back().DelayedDecltypeBinds.push_back(Bind);
74330b57cec5SDimitry Andric 
74340b57cec5SDimitry Andric   return Bind;
74350b57cec5SDimitry Andric }
74360b57cec5SDimitry Andric 
74370b57cec5SDimitry Andric ExprResult
MaybeCreateExprWithCleanups(ExprResult SubExpr)74380b57cec5SDimitry Andric Sema::MaybeCreateExprWithCleanups(ExprResult SubExpr) {
74390b57cec5SDimitry Andric   if (SubExpr.isInvalid())
74400b57cec5SDimitry Andric     return ExprError();
74410b57cec5SDimitry Andric 
74420b57cec5SDimitry Andric   return MaybeCreateExprWithCleanups(SubExpr.get());
74430b57cec5SDimitry Andric }
74440b57cec5SDimitry Andric 
MaybeCreateExprWithCleanups(Expr * SubExpr)74450b57cec5SDimitry Andric Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) {
74460b57cec5SDimitry Andric   assert(SubExpr && "subexpression can't be null!");
74470b57cec5SDimitry Andric 
74480b57cec5SDimitry Andric   CleanupVarDeclMarking();
74490b57cec5SDimitry Andric 
74500b57cec5SDimitry Andric   unsigned FirstCleanup = ExprEvalContexts.back().NumCleanupObjects;
74510b57cec5SDimitry Andric   assert(ExprCleanupObjects.size() >= FirstCleanup);
74520b57cec5SDimitry Andric   assert(Cleanup.exprNeedsCleanups() ||
74530b57cec5SDimitry Andric          ExprCleanupObjects.size() == FirstCleanup);
74540b57cec5SDimitry Andric   if (!Cleanup.exprNeedsCleanups())
74550b57cec5SDimitry Andric     return SubExpr;
74560b57cec5SDimitry Andric 
7457bdd1243dSDimitry Andric   auto Cleanups = llvm::ArrayRef(ExprCleanupObjects.begin() + FirstCleanup,
74580b57cec5SDimitry Andric                                  ExprCleanupObjects.size() - FirstCleanup);
74590b57cec5SDimitry Andric 
74600b57cec5SDimitry Andric   auto *E = ExprWithCleanups::Create(
74610b57cec5SDimitry Andric       Context, SubExpr, Cleanup.cleanupsHaveSideEffects(), Cleanups);
74620b57cec5SDimitry Andric   DiscardCleanupsInEvaluationContext();
74630b57cec5SDimitry Andric 
74640b57cec5SDimitry Andric   return E;
74650b57cec5SDimitry Andric }
74660b57cec5SDimitry Andric 
MaybeCreateStmtWithCleanups(Stmt * SubStmt)74670b57cec5SDimitry Andric Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) {
74680b57cec5SDimitry Andric   assert(SubStmt && "sub-statement can't be null!");
74690b57cec5SDimitry Andric 
74700b57cec5SDimitry Andric   CleanupVarDeclMarking();
74710b57cec5SDimitry Andric 
74720b57cec5SDimitry Andric   if (!Cleanup.exprNeedsCleanups())
74730b57cec5SDimitry Andric     return SubStmt;
74740b57cec5SDimitry Andric 
74750b57cec5SDimitry Andric   // FIXME: In order to attach the temporaries, wrap the statement into
74760b57cec5SDimitry Andric   // a StmtExpr; currently this is only used for asm statements.
74770b57cec5SDimitry Andric   // This is hacky, either create a new CXXStmtWithTemporaries statement or
74780b57cec5SDimitry Andric   // a new AsmStmtWithTemporaries.
747981ad6265SDimitry Andric   CompoundStmt *CompStmt =
748081ad6265SDimitry Andric       CompoundStmt::Create(Context, SubStmt, FPOptionsOverride(),
748181ad6265SDimitry Andric                            SourceLocation(), SourceLocation());
74828c27c554SDimitry Andric   Expr *E = new (Context)
74838c27c554SDimitry Andric       StmtExpr(CompStmt, Context.VoidTy, SourceLocation(), SourceLocation(),
7484cd675bb6SDimitry Andric                /*FIXME TemplateDepth=*/0);
74850b57cec5SDimitry Andric   return MaybeCreateExprWithCleanups(E);
74860b57cec5SDimitry Andric }
74870b57cec5SDimitry Andric 
74880b57cec5SDimitry Andric /// Process the expression contained within a decltype. For such expressions,
74890b57cec5SDimitry Andric /// certain semantic checks on temporaries are delayed until this point, and
74900b57cec5SDimitry Andric /// are omitted for the 'topmost' call in the decltype expression. If the
74910b57cec5SDimitry Andric /// topmost call bound a temporary, strip that temporary off the expression.
ActOnDecltypeExpression(Expr * E)74920b57cec5SDimitry Andric ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
74930b57cec5SDimitry Andric   assert(ExprEvalContexts.back().ExprContext ==
74940b57cec5SDimitry Andric              ExpressionEvaluationContextRecord::EK_Decltype &&
74950b57cec5SDimitry Andric          "not in a decltype expression");
74960b57cec5SDimitry Andric 
74970b57cec5SDimitry Andric   ExprResult Result = CheckPlaceholderExpr(E);
74980b57cec5SDimitry Andric   if (Result.isInvalid())
74990b57cec5SDimitry Andric     return ExprError();
75000b57cec5SDimitry Andric   E = Result.get();
75010b57cec5SDimitry Andric 
75020b57cec5SDimitry Andric   // C++11 [expr.call]p11:
75030b57cec5SDimitry Andric   //   If a function call is a prvalue of object type,
75040b57cec5SDimitry Andric   // -- if the function call is either
75050b57cec5SDimitry Andric   //   -- the operand of a decltype-specifier, or
75060b57cec5SDimitry Andric   //   -- the right operand of a comma operator that is the operand of a
75070b57cec5SDimitry Andric   //      decltype-specifier,
75080b57cec5SDimitry Andric   //   a temporary object is not introduced for the prvalue.
75090b57cec5SDimitry Andric 
75100b57cec5SDimitry Andric   // Recursively rebuild ParenExprs and comma expressions to strip out the
75110b57cec5SDimitry Andric   // outermost CXXBindTemporaryExpr, if any.
75120b57cec5SDimitry Andric   if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
75130b57cec5SDimitry Andric     ExprResult SubExpr = ActOnDecltypeExpression(PE->getSubExpr());
75140b57cec5SDimitry Andric     if (SubExpr.isInvalid())
75150b57cec5SDimitry Andric       return ExprError();
75160b57cec5SDimitry Andric     if (SubExpr.get() == PE->getSubExpr())
75170b57cec5SDimitry Andric       return E;
75180b57cec5SDimitry Andric     return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.get());
75190b57cec5SDimitry Andric   }
75200b57cec5SDimitry Andric   if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
75210b57cec5SDimitry Andric     if (BO->getOpcode() == BO_Comma) {
75220b57cec5SDimitry Andric       ExprResult RHS = ActOnDecltypeExpression(BO->getRHS());
75230b57cec5SDimitry Andric       if (RHS.isInvalid())
75240b57cec5SDimitry Andric         return ExprError();
75250b57cec5SDimitry Andric       if (RHS.get() == BO->getRHS())
75260b57cec5SDimitry Andric         return E;
75275ffd83dbSDimitry Andric       return BinaryOperator::Create(Context, BO->getLHS(), RHS.get(), BO_Comma,
75285ffd83dbSDimitry Andric                                     BO->getType(), BO->getValueKind(),
75295ffd83dbSDimitry Andric                                     BO->getObjectKind(), BO->getOperatorLoc(),
7530bdd1243dSDimitry Andric                                     BO->getFPFeatures());
75310b57cec5SDimitry Andric     }
75320b57cec5SDimitry Andric   }
75330b57cec5SDimitry Andric 
75340b57cec5SDimitry Andric   CXXBindTemporaryExpr *TopBind = dyn_cast<CXXBindTemporaryExpr>(E);
75350b57cec5SDimitry Andric   CallExpr *TopCall = TopBind ? dyn_cast<CallExpr>(TopBind->getSubExpr())
75360b57cec5SDimitry Andric                               : nullptr;
75370b57cec5SDimitry Andric   if (TopCall)
75380b57cec5SDimitry Andric     E = TopCall;
75390b57cec5SDimitry Andric   else
75400b57cec5SDimitry Andric     TopBind = nullptr;
75410b57cec5SDimitry Andric 
75420b57cec5SDimitry Andric   // Disable the special decltype handling now.
75430b57cec5SDimitry Andric   ExprEvalContexts.back().ExprContext =
75440b57cec5SDimitry Andric       ExpressionEvaluationContextRecord::EK_Other;
75450b57cec5SDimitry Andric 
7546a7dea167SDimitry Andric   Result = CheckUnevaluatedOperand(E);
7547a7dea167SDimitry Andric   if (Result.isInvalid())
7548a7dea167SDimitry Andric     return ExprError();
7549a7dea167SDimitry Andric   E = Result.get();
7550a7dea167SDimitry Andric 
75510b57cec5SDimitry Andric   // In MS mode, don't perform any extra checking of call return types within a
75520b57cec5SDimitry Andric   // decltype expression.
75530b57cec5SDimitry Andric   if (getLangOpts().MSVCCompat)
75540b57cec5SDimitry Andric     return E;
75550b57cec5SDimitry Andric 
75560b57cec5SDimitry Andric   // Perform the semantic checks we delayed until this point.
75570b57cec5SDimitry Andric   for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeCalls.size();
75580b57cec5SDimitry Andric        I != N; ++I) {
75590b57cec5SDimitry Andric     CallExpr *Call = ExprEvalContexts.back().DelayedDecltypeCalls[I];
75600b57cec5SDimitry Andric     if (Call == TopCall)
75610b57cec5SDimitry Andric       continue;
75620b57cec5SDimitry Andric 
75630b57cec5SDimitry Andric     if (CheckCallReturnType(Call->getCallReturnType(Context),
75640b57cec5SDimitry Andric                             Call->getBeginLoc(), Call, Call->getDirectCallee()))
75650b57cec5SDimitry Andric       return ExprError();
75660b57cec5SDimitry Andric   }
75670b57cec5SDimitry Andric 
75680b57cec5SDimitry Andric   // Now all relevant types are complete, check the destructors are accessible
75690b57cec5SDimitry Andric   // and non-deleted, and annotate them on the temporaries.
75700b57cec5SDimitry Andric   for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeBinds.size();
75710b57cec5SDimitry Andric        I != N; ++I) {
75720b57cec5SDimitry Andric     CXXBindTemporaryExpr *Bind =
75730b57cec5SDimitry Andric       ExprEvalContexts.back().DelayedDecltypeBinds[I];
75740b57cec5SDimitry Andric     if (Bind == TopBind)
75750b57cec5SDimitry Andric       continue;
75760b57cec5SDimitry Andric 
75770b57cec5SDimitry Andric     CXXTemporary *Temp = Bind->getTemporary();
75780b57cec5SDimitry Andric 
75790b57cec5SDimitry Andric     CXXRecordDecl *RD =
75800b57cec5SDimitry Andric       Bind->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
75810b57cec5SDimitry Andric     CXXDestructorDecl *Destructor = LookupDestructor(RD);
75820b57cec5SDimitry Andric     Temp->setDestructor(Destructor);
75830b57cec5SDimitry Andric 
75840b57cec5SDimitry Andric     MarkFunctionReferenced(Bind->getExprLoc(), Destructor);
75850b57cec5SDimitry Andric     CheckDestructorAccess(Bind->getExprLoc(), Destructor,
75860b57cec5SDimitry Andric                           PDiag(diag::err_access_dtor_temp)
75870b57cec5SDimitry Andric                             << Bind->getType());
75880b57cec5SDimitry Andric     if (DiagnoseUseOfDecl(Destructor, Bind->getExprLoc()))
75890b57cec5SDimitry Andric       return ExprError();
75900b57cec5SDimitry Andric 
75910b57cec5SDimitry Andric     // We need a cleanup, but we don't need to remember the temporary.
75920b57cec5SDimitry Andric     Cleanup.setExprNeedsCleanups(true);
75930b57cec5SDimitry Andric   }
75940b57cec5SDimitry Andric 
75950b57cec5SDimitry Andric   // Possibly strip off the top CXXBindTemporaryExpr.
75960b57cec5SDimitry Andric   return E;
75970b57cec5SDimitry Andric }
75980b57cec5SDimitry Andric 
75990b57cec5SDimitry Andric /// Note a set of 'operator->' functions that were used for a member access.
noteOperatorArrows(Sema & S,ArrayRef<FunctionDecl * > OperatorArrows)76000b57cec5SDimitry Andric static void noteOperatorArrows(Sema &S,
76010b57cec5SDimitry Andric                                ArrayRef<FunctionDecl *> OperatorArrows) {
76020b57cec5SDimitry Andric   unsigned SkipStart = OperatorArrows.size(), SkipCount = 0;
76030b57cec5SDimitry Andric   // FIXME: Make this configurable?
76040b57cec5SDimitry Andric   unsigned Limit = 9;
76050b57cec5SDimitry Andric   if (OperatorArrows.size() > Limit) {
76060b57cec5SDimitry Andric     // Produce Limit-1 normal notes and one 'skipping' note.
76070b57cec5SDimitry Andric     SkipStart = (Limit - 1) / 2 + (Limit - 1) % 2;
76080b57cec5SDimitry Andric     SkipCount = OperatorArrows.size() - (Limit - 1);
76090b57cec5SDimitry Andric   }
76100b57cec5SDimitry Andric 
76110b57cec5SDimitry Andric   for (unsigned I = 0; I < OperatorArrows.size(); /**/) {
76120b57cec5SDimitry Andric     if (I == SkipStart) {
76130b57cec5SDimitry Andric       S.Diag(OperatorArrows[I]->getLocation(),
76140b57cec5SDimitry Andric              diag::note_operator_arrows_suppressed)
76150b57cec5SDimitry Andric           << SkipCount;
76160b57cec5SDimitry Andric       I += SkipCount;
76170b57cec5SDimitry Andric     } else {
76180b57cec5SDimitry Andric       S.Diag(OperatorArrows[I]->getLocation(), diag::note_operator_arrow_here)
76190b57cec5SDimitry Andric           << OperatorArrows[I]->getCallResultType();
76200b57cec5SDimitry Andric       ++I;
76210b57cec5SDimitry Andric     }
76220b57cec5SDimitry Andric   }
76230b57cec5SDimitry Andric }
76240b57cec5SDimitry Andric 
ActOnStartCXXMemberReference(Scope * S,Expr * Base,SourceLocation OpLoc,tok::TokenKind OpKind,ParsedType & ObjectType,bool & MayBePseudoDestructor)76250b57cec5SDimitry Andric ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
76260b57cec5SDimitry Andric                                               SourceLocation OpLoc,
76270b57cec5SDimitry Andric                                               tok::TokenKind OpKind,
76280b57cec5SDimitry Andric                                               ParsedType &ObjectType,
76290b57cec5SDimitry Andric                                               bool &MayBePseudoDestructor) {
76300b57cec5SDimitry Andric   // Since this might be a postfix expression, get rid of ParenListExprs.
76310b57cec5SDimitry Andric   ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
76320b57cec5SDimitry Andric   if (Result.isInvalid()) return ExprError();
76330b57cec5SDimitry Andric   Base = Result.get();
76340b57cec5SDimitry Andric 
76350b57cec5SDimitry Andric   Result = CheckPlaceholderExpr(Base);
76360b57cec5SDimitry Andric   if (Result.isInvalid()) return ExprError();
76370b57cec5SDimitry Andric   Base = Result.get();
76380b57cec5SDimitry Andric 
76390b57cec5SDimitry Andric   QualType BaseType = Base->getType();
76400b57cec5SDimitry Andric   MayBePseudoDestructor = false;
76410b57cec5SDimitry Andric   if (BaseType->isDependentType()) {
76420b57cec5SDimitry Andric     // If we have a pointer to a dependent type and are using the -> operator,
76430b57cec5SDimitry Andric     // the object type is the type that the pointer points to. We might still
76440b57cec5SDimitry Andric     // have enough information about that type to do something useful.
76450b57cec5SDimitry Andric     if (OpKind == tok::arrow)
76460b57cec5SDimitry Andric       if (const PointerType *Ptr = BaseType->getAs<PointerType>())
76470b57cec5SDimitry Andric         BaseType = Ptr->getPointeeType();
76480b57cec5SDimitry Andric 
76490b57cec5SDimitry Andric     ObjectType = ParsedType::make(BaseType);
76500b57cec5SDimitry Andric     MayBePseudoDestructor = true;
76510b57cec5SDimitry Andric     return Base;
76520b57cec5SDimitry Andric   }
76530b57cec5SDimitry Andric 
76540b57cec5SDimitry Andric   // C++ [over.match.oper]p8:
76550b57cec5SDimitry Andric   //   [...] When operator->returns, the operator-> is applied  to the value
76560b57cec5SDimitry Andric   //   returned, with the original second operand.
76570b57cec5SDimitry Andric   if (OpKind == tok::arrow) {
76580b57cec5SDimitry Andric     QualType StartingType = BaseType;
76590b57cec5SDimitry Andric     bool NoArrowOperatorFound = false;
76600b57cec5SDimitry Andric     bool FirstIteration = true;
76610b57cec5SDimitry Andric     FunctionDecl *CurFD = dyn_cast<FunctionDecl>(CurContext);
76620b57cec5SDimitry Andric     // The set of types we've considered so far.
76630b57cec5SDimitry Andric     llvm::SmallPtrSet<CanQualType,8> CTypes;
76640b57cec5SDimitry Andric     SmallVector<FunctionDecl*, 8> OperatorArrows;
76650b57cec5SDimitry Andric     CTypes.insert(Context.getCanonicalType(BaseType));
76660b57cec5SDimitry Andric 
76670b57cec5SDimitry Andric     while (BaseType->isRecordType()) {
76680b57cec5SDimitry Andric       if (OperatorArrows.size() >= getLangOpts().ArrowDepth) {
76690b57cec5SDimitry Andric         Diag(OpLoc, diag::err_operator_arrow_depth_exceeded)
76700b57cec5SDimitry Andric           << StartingType << getLangOpts().ArrowDepth << Base->getSourceRange();
76710b57cec5SDimitry Andric         noteOperatorArrows(*this, OperatorArrows);
76720b57cec5SDimitry Andric         Diag(OpLoc, diag::note_operator_arrow_depth)
76730b57cec5SDimitry Andric           << getLangOpts().ArrowDepth;
76740b57cec5SDimitry Andric         return ExprError();
76750b57cec5SDimitry Andric       }
76760b57cec5SDimitry Andric 
76770b57cec5SDimitry Andric       Result = BuildOverloadedArrowExpr(
76780b57cec5SDimitry Andric           S, Base, OpLoc,
76790b57cec5SDimitry Andric           // When in a template specialization and on the first loop iteration,
76800b57cec5SDimitry Andric           // potentially give the default diagnostic (with the fixit in a
76810b57cec5SDimitry Andric           // separate note) instead of having the error reported back to here
76820b57cec5SDimitry Andric           // and giving a diagnostic with a fixit attached to the error itself.
76830b57cec5SDimitry Andric           (FirstIteration && CurFD && CurFD->isFunctionTemplateSpecialization())
76840b57cec5SDimitry Andric               ? nullptr
76850b57cec5SDimitry Andric               : &NoArrowOperatorFound);
76860b57cec5SDimitry Andric       if (Result.isInvalid()) {
76870b57cec5SDimitry Andric         if (NoArrowOperatorFound) {
76880b57cec5SDimitry Andric           if (FirstIteration) {
76890b57cec5SDimitry Andric             Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
76900b57cec5SDimitry Andric               << BaseType << 1 << Base->getSourceRange()
76910b57cec5SDimitry Andric               << FixItHint::CreateReplacement(OpLoc, ".");
76920b57cec5SDimitry Andric             OpKind = tok::period;
76930b57cec5SDimitry Andric             break;
76940b57cec5SDimitry Andric           }
76950b57cec5SDimitry Andric           Diag(OpLoc, diag::err_typecheck_member_reference_arrow)
76960b57cec5SDimitry Andric             << BaseType << Base->getSourceRange();
76970b57cec5SDimitry Andric           CallExpr *CE = dyn_cast<CallExpr>(Base);
76980b57cec5SDimitry Andric           if (Decl *CD = (CE ? CE->getCalleeDecl() : nullptr)) {
76990b57cec5SDimitry Andric             Diag(CD->getBeginLoc(),
77000b57cec5SDimitry Andric                  diag::note_member_reference_arrow_from_operator_arrow);
77010b57cec5SDimitry Andric           }
77020b57cec5SDimitry Andric         }
77030b57cec5SDimitry Andric         return ExprError();
77040b57cec5SDimitry Andric       }
77050b57cec5SDimitry Andric       Base = Result.get();
77060b57cec5SDimitry Andric       if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(Base))
77070b57cec5SDimitry Andric         OperatorArrows.push_back(OpCall->getDirectCallee());
77080b57cec5SDimitry Andric       BaseType = Base->getType();
77090b57cec5SDimitry Andric       CanQualType CBaseType = Context.getCanonicalType(BaseType);
77100b57cec5SDimitry Andric       if (!CTypes.insert(CBaseType).second) {
77110b57cec5SDimitry Andric         Diag(OpLoc, diag::err_operator_arrow_circular) << StartingType;
77120b57cec5SDimitry Andric         noteOperatorArrows(*this, OperatorArrows);
77130b57cec5SDimitry Andric         return ExprError();
77140b57cec5SDimitry Andric       }
77150b57cec5SDimitry Andric       FirstIteration = false;
77160b57cec5SDimitry Andric     }
77170b57cec5SDimitry Andric 
77180b57cec5SDimitry Andric     if (OpKind == tok::arrow) {
77190b57cec5SDimitry Andric       if (BaseType->isPointerType())
77200b57cec5SDimitry Andric         BaseType = BaseType->getPointeeType();
77210b57cec5SDimitry Andric       else if (auto *AT = Context.getAsArrayType(BaseType))
77220b57cec5SDimitry Andric         BaseType = AT->getElementType();
77230b57cec5SDimitry Andric     }
77240b57cec5SDimitry Andric   }
77250b57cec5SDimitry Andric 
77260b57cec5SDimitry Andric   // Objective-C properties allow "." access on Objective-C pointer types,
77270b57cec5SDimitry Andric   // so adjust the base type to the object type itself.
77280b57cec5SDimitry Andric   if (BaseType->isObjCObjectPointerType())
77290b57cec5SDimitry Andric     BaseType = BaseType->getPointeeType();
77300b57cec5SDimitry Andric 
77310b57cec5SDimitry Andric   // C++ [basic.lookup.classref]p2:
77320b57cec5SDimitry Andric   //   [...] If the type of the object expression is of pointer to scalar
77330b57cec5SDimitry Andric   //   type, the unqualified-id is looked up in the context of the complete
77340b57cec5SDimitry Andric   //   postfix-expression.
77350b57cec5SDimitry Andric   //
77360b57cec5SDimitry Andric   // This also indicates that we could be parsing a pseudo-destructor-name.
77370b57cec5SDimitry Andric   // Note that Objective-C class and object types can be pseudo-destructor
77380b57cec5SDimitry Andric   // expressions or normal member (ivar or property) access expressions, and
77390b57cec5SDimitry Andric   // it's legal for the type to be incomplete if this is a pseudo-destructor
77400b57cec5SDimitry Andric   // call.  We'll do more incomplete-type checks later in the lookup process,
77410b57cec5SDimitry Andric   // so just skip this check for ObjC types.
77420b57cec5SDimitry Andric   if (!BaseType->isRecordType()) {
77430b57cec5SDimitry Andric     ObjectType = ParsedType::make(BaseType);
77440b57cec5SDimitry Andric     MayBePseudoDestructor = true;
77450b57cec5SDimitry Andric     return Base;
77460b57cec5SDimitry Andric   }
77470b57cec5SDimitry Andric 
77480b57cec5SDimitry Andric   // The object type must be complete (or dependent), or
77490b57cec5SDimitry Andric   // C++11 [expr.prim.general]p3:
77500b57cec5SDimitry Andric   //   Unlike the object expression in other contexts, *this is not required to
77510b57cec5SDimitry Andric   //   be of complete type for purposes of class member access (5.2.5) outside
77520b57cec5SDimitry Andric   //   the member function body.
77530b57cec5SDimitry Andric   if (!BaseType->isDependentType() &&
77540b57cec5SDimitry Andric       !isThisOutsideMemberFunctionBody(BaseType) &&
775504eeddc0SDimitry Andric       RequireCompleteType(OpLoc, BaseType,
775604eeddc0SDimitry Andric                           diag::err_incomplete_member_access)) {
775704eeddc0SDimitry Andric     return CreateRecoveryExpr(Base->getBeginLoc(), Base->getEndLoc(), {Base});
775804eeddc0SDimitry Andric   }
77590b57cec5SDimitry Andric 
77600b57cec5SDimitry Andric   // C++ [basic.lookup.classref]p2:
77610b57cec5SDimitry Andric   //   If the id-expression in a class member access (5.2.5) is an
77620b57cec5SDimitry Andric   //   unqualified-id, and the type of the object expression is of a class
77630b57cec5SDimitry Andric   //   type C (or of pointer to a class type C), the unqualified-id is looked
77640b57cec5SDimitry Andric   //   up in the scope of class C. [...]
77650b57cec5SDimitry Andric   ObjectType = ParsedType::make(BaseType);
77660b57cec5SDimitry Andric   return Base;
77670b57cec5SDimitry Andric }
77680b57cec5SDimitry Andric 
CheckArrow(Sema & S,QualType & ObjectType,Expr * & Base,tok::TokenKind & OpKind,SourceLocation OpLoc)77690b57cec5SDimitry Andric static bool CheckArrow(Sema &S, QualType &ObjectType, Expr *&Base,
77700b57cec5SDimitry Andric                        tok::TokenKind &OpKind, SourceLocation OpLoc) {
77710b57cec5SDimitry Andric   if (Base->hasPlaceholderType()) {
77720b57cec5SDimitry Andric     ExprResult result = S.CheckPlaceholderExpr(Base);
77730b57cec5SDimitry Andric     if (result.isInvalid()) return true;
77740b57cec5SDimitry Andric     Base = result.get();
77750b57cec5SDimitry Andric   }
77760b57cec5SDimitry Andric   ObjectType = Base->getType();
77770b57cec5SDimitry Andric 
77780b57cec5SDimitry Andric   // C++ [expr.pseudo]p2:
77790b57cec5SDimitry Andric   //   The left-hand side of the dot operator shall be of scalar type. The
77800b57cec5SDimitry Andric   //   left-hand side of the arrow operator shall be of pointer to scalar type.
77810b57cec5SDimitry Andric   //   This scalar type is the object type.
77820b57cec5SDimitry Andric   // Note that this is rather different from the normal handling for the
77830b57cec5SDimitry Andric   // arrow operator.
77840b57cec5SDimitry Andric   if (OpKind == tok::arrow) {
7785e8d8bef9SDimitry Andric     // The operator requires a prvalue, so perform lvalue conversions.
7786e8d8bef9SDimitry Andric     // Only do this if we might plausibly end with a pointer, as otherwise
7787e8d8bef9SDimitry Andric     // this was likely to be intended to be a '.'.
7788e8d8bef9SDimitry Andric     if (ObjectType->isPointerType() || ObjectType->isArrayType() ||
7789e8d8bef9SDimitry Andric         ObjectType->isFunctionType()) {
7790e8d8bef9SDimitry Andric       ExprResult BaseResult = S.DefaultFunctionArrayLvalueConversion(Base);
7791e8d8bef9SDimitry Andric       if (BaseResult.isInvalid())
7792e8d8bef9SDimitry Andric         return true;
7793e8d8bef9SDimitry Andric       Base = BaseResult.get();
7794e8d8bef9SDimitry Andric       ObjectType = Base->getType();
7795e8d8bef9SDimitry Andric     }
7796e8d8bef9SDimitry Andric 
77970b57cec5SDimitry Andric     if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
77980b57cec5SDimitry Andric       ObjectType = Ptr->getPointeeType();
77990b57cec5SDimitry Andric     } else if (!Base->isTypeDependent()) {
78000b57cec5SDimitry Andric       // The user wrote "p->" when they probably meant "p."; fix it.
78010b57cec5SDimitry Andric       S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
78020b57cec5SDimitry Andric         << ObjectType << true
78030b57cec5SDimitry Andric         << FixItHint::CreateReplacement(OpLoc, ".");
78040b57cec5SDimitry Andric       if (S.isSFINAEContext())
78050b57cec5SDimitry Andric         return true;
78060b57cec5SDimitry Andric 
78070b57cec5SDimitry Andric       OpKind = tok::period;
78080b57cec5SDimitry Andric     }
78090b57cec5SDimitry Andric   }
78100b57cec5SDimitry Andric 
78110b57cec5SDimitry Andric   return false;
78120b57cec5SDimitry Andric }
78130b57cec5SDimitry Andric 
78140b57cec5SDimitry Andric /// Check if it's ok to try and recover dot pseudo destructor calls on
78150b57cec5SDimitry Andric /// pointer objects.
78160b57cec5SDimitry Andric static bool
canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema & SemaRef,QualType DestructedType)78170b57cec5SDimitry Andric canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema &SemaRef,
78180b57cec5SDimitry Andric                                                    QualType DestructedType) {
78190b57cec5SDimitry Andric   // If this is a record type, check if its destructor is callable.
78200b57cec5SDimitry Andric   if (auto *RD = DestructedType->getAsCXXRecordDecl()) {
78210b57cec5SDimitry Andric     if (RD->hasDefinition())
78220b57cec5SDimitry Andric       if (CXXDestructorDecl *D = SemaRef.LookupDestructor(RD))
78230b57cec5SDimitry Andric         return SemaRef.CanUseDecl(D, /*TreatUnavailableAsInvalid=*/false);
78240b57cec5SDimitry Andric     return false;
78250b57cec5SDimitry Andric   }
78260b57cec5SDimitry Andric 
78270b57cec5SDimitry Andric   // Otherwise, check if it's a type for which it's valid to use a pseudo-dtor.
78280b57cec5SDimitry Andric   return DestructedType->isDependentType() || DestructedType->isScalarType() ||
78290b57cec5SDimitry Andric          DestructedType->isVectorType();
78300b57cec5SDimitry Andric }
78310b57cec5SDimitry Andric 
BuildPseudoDestructorExpr(Expr * Base,SourceLocation OpLoc,tok::TokenKind OpKind,const CXXScopeSpec & SS,TypeSourceInfo * ScopeTypeInfo,SourceLocation CCLoc,SourceLocation TildeLoc,PseudoDestructorTypeStorage Destructed)78320b57cec5SDimitry Andric ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
78330b57cec5SDimitry Andric                                            SourceLocation OpLoc,
78340b57cec5SDimitry Andric                                            tok::TokenKind OpKind,
78350b57cec5SDimitry Andric                                            const CXXScopeSpec &SS,
78360b57cec5SDimitry Andric                                            TypeSourceInfo *ScopeTypeInfo,
78370b57cec5SDimitry Andric                                            SourceLocation CCLoc,
78380b57cec5SDimitry Andric                                            SourceLocation TildeLoc,
78390b57cec5SDimitry Andric                                          PseudoDestructorTypeStorage Destructed) {
78400b57cec5SDimitry Andric   TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo();
78410b57cec5SDimitry Andric 
78420b57cec5SDimitry Andric   QualType ObjectType;
78430b57cec5SDimitry Andric   if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
78440b57cec5SDimitry Andric     return ExprError();
78450b57cec5SDimitry Andric 
78460b57cec5SDimitry Andric   if (!ObjectType->isDependentType() && !ObjectType->isScalarType() &&
78470b57cec5SDimitry Andric       !ObjectType->isVectorType()) {
78480b57cec5SDimitry Andric     if (getLangOpts().MSVCCompat && ObjectType->isVoidType())
78490b57cec5SDimitry Andric       Diag(OpLoc, diag::ext_pseudo_dtor_on_void) << Base->getSourceRange();
78500b57cec5SDimitry Andric     else {
78510b57cec5SDimitry Andric       Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
78520b57cec5SDimitry Andric         << ObjectType << Base->getSourceRange();
78530b57cec5SDimitry Andric       return ExprError();
78540b57cec5SDimitry Andric     }
78550b57cec5SDimitry Andric   }
78560b57cec5SDimitry Andric 
78570b57cec5SDimitry Andric   // C++ [expr.pseudo]p2:
78580b57cec5SDimitry Andric   //   [...] The cv-unqualified versions of the object type and of the type
78590b57cec5SDimitry Andric   //   designated by the pseudo-destructor-name shall be the same type.
78600b57cec5SDimitry Andric   if (DestructedTypeInfo) {
78610b57cec5SDimitry Andric     QualType DestructedType = DestructedTypeInfo->getType();
7862bdd1243dSDimitry Andric     SourceLocation DestructedTypeStart =
7863bdd1243dSDimitry Andric         DestructedTypeInfo->getTypeLoc().getBeginLoc();
78640b57cec5SDimitry Andric     if (!DestructedType->isDependentType() && !ObjectType->isDependentType()) {
78650b57cec5SDimitry Andric       if (!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
78660b57cec5SDimitry Andric         // Detect dot pseudo destructor calls on pointer objects, e.g.:
78670b57cec5SDimitry Andric         //   Foo *foo;
78680b57cec5SDimitry Andric         //   foo.~Foo();
78690b57cec5SDimitry Andric         if (OpKind == tok::period && ObjectType->isPointerType() &&
78700b57cec5SDimitry Andric             Context.hasSameUnqualifiedType(DestructedType,
78710b57cec5SDimitry Andric                                            ObjectType->getPointeeType())) {
78720b57cec5SDimitry Andric           auto Diagnostic =
78730b57cec5SDimitry Andric               Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
78740b57cec5SDimitry Andric               << ObjectType << /*IsArrow=*/0 << Base->getSourceRange();
78750b57cec5SDimitry Andric 
78760b57cec5SDimitry Andric           // Issue a fixit only when the destructor is valid.
78770b57cec5SDimitry Andric           if (canRecoverDotPseudoDestructorCallsOnPointerObjects(
78780b57cec5SDimitry Andric                   *this, DestructedType))
78790b57cec5SDimitry Andric             Diagnostic << FixItHint::CreateReplacement(OpLoc, "->");
78800b57cec5SDimitry Andric 
78810b57cec5SDimitry Andric           // Recover by setting the object type to the destructed type and the
78820b57cec5SDimitry Andric           // operator to '->'.
78830b57cec5SDimitry Andric           ObjectType = DestructedType;
78840b57cec5SDimitry Andric           OpKind = tok::arrow;
78850b57cec5SDimitry Andric         } else {
78860b57cec5SDimitry Andric           Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
78870b57cec5SDimitry Andric               << ObjectType << DestructedType << Base->getSourceRange()
7888bdd1243dSDimitry Andric               << DestructedTypeInfo->getTypeLoc().getSourceRange();
78890b57cec5SDimitry Andric 
78900b57cec5SDimitry Andric           // Recover by setting the destructed type to the object type.
78910b57cec5SDimitry Andric           DestructedType = ObjectType;
78920b57cec5SDimitry Andric           DestructedTypeInfo =
78930b57cec5SDimitry Andric               Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart);
78940b57cec5SDimitry Andric           Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
78950b57cec5SDimitry Andric         }
78960b57cec5SDimitry Andric       } else if (DestructedType.getObjCLifetime() !=
78970b57cec5SDimitry Andric                                                 ObjectType.getObjCLifetime()) {
78980b57cec5SDimitry Andric 
78990b57cec5SDimitry Andric         if (DestructedType.getObjCLifetime() == Qualifiers::OCL_None) {
79000b57cec5SDimitry Andric           // Okay: just pretend that the user provided the correctly-qualified
79010b57cec5SDimitry Andric           // type.
79020b57cec5SDimitry Andric         } else {
79030b57cec5SDimitry Andric           Diag(DestructedTypeStart, diag::err_arc_pseudo_dtor_inconstant_quals)
79040b57cec5SDimitry Andric               << ObjectType << DestructedType << Base->getSourceRange()
7905bdd1243dSDimitry Andric               << DestructedTypeInfo->getTypeLoc().getSourceRange();
79060b57cec5SDimitry Andric         }
79070b57cec5SDimitry Andric 
79080b57cec5SDimitry Andric         // Recover by setting the destructed type to the object type.
79090b57cec5SDimitry Andric         DestructedType = ObjectType;
79100b57cec5SDimitry Andric         DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType,
79110b57cec5SDimitry Andric                                                            DestructedTypeStart);
79120b57cec5SDimitry Andric         Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
79130b57cec5SDimitry Andric       }
79140b57cec5SDimitry Andric     }
79150b57cec5SDimitry Andric   }
79160b57cec5SDimitry Andric 
79170b57cec5SDimitry Andric   // C++ [expr.pseudo]p2:
79180b57cec5SDimitry Andric   //   [...] Furthermore, the two type-names in a pseudo-destructor-name of the
79190b57cec5SDimitry Andric   //   form
79200b57cec5SDimitry Andric   //
79210b57cec5SDimitry Andric   //     ::[opt] nested-name-specifier[opt] type-name :: ~ type-name
79220b57cec5SDimitry Andric   //
79230b57cec5SDimitry Andric   //   shall designate the same scalar type.
79240b57cec5SDimitry Andric   if (ScopeTypeInfo) {
79250b57cec5SDimitry Andric     QualType ScopeType = ScopeTypeInfo->getType();
79260b57cec5SDimitry Andric     if (!ScopeType->isDependentType() && !ObjectType->isDependentType() &&
79270b57cec5SDimitry Andric         !Context.hasSameUnqualifiedType(ScopeType, ObjectType)) {
79280b57cec5SDimitry Andric 
7929bdd1243dSDimitry Andric       Diag(ScopeTypeInfo->getTypeLoc().getSourceRange().getBegin(),
79300b57cec5SDimitry Andric            diag::err_pseudo_dtor_type_mismatch)
79310b57cec5SDimitry Andric           << ObjectType << ScopeType << Base->getSourceRange()
7932bdd1243dSDimitry Andric           << ScopeTypeInfo->getTypeLoc().getSourceRange();
79330b57cec5SDimitry Andric 
79340b57cec5SDimitry Andric       ScopeType = QualType();
79350b57cec5SDimitry Andric       ScopeTypeInfo = nullptr;
79360b57cec5SDimitry Andric     }
79370b57cec5SDimitry Andric   }
79380b57cec5SDimitry Andric 
79390b57cec5SDimitry Andric   Expr *Result
79400b57cec5SDimitry Andric     = new (Context) CXXPseudoDestructorExpr(Context, Base,
79410b57cec5SDimitry Andric                                             OpKind == tok::arrow, OpLoc,
79420b57cec5SDimitry Andric                                             SS.getWithLocInContext(Context),
79430b57cec5SDimitry Andric                                             ScopeTypeInfo,
79440b57cec5SDimitry Andric                                             CCLoc,
79450b57cec5SDimitry Andric                                             TildeLoc,
79460b57cec5SDimitry Andric                                             Destructed);
79470b57cec5SDimitry Andric 
79480b57cec5SDimitry Andric   return Result;
79490b57cec5SDimitry Andric }
79500b57cec5SDimitry Andric 
ActOnPseudoDestructorExpr(Scope * S,Expr * Base,SourceLocation OpLoc,tok::TokenKind OpKind,CXXScopeSpec & SS,UnqualifiedId & FirstTypeName,SourceLocation CCLoc,SourceLocation TildeLoc,UnqualifiedId & SecondTypeName)79510b57cec5SDimitry Andric ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
79520b57cec5SDimitry Andric                                            SourceLocation OpLoc,
79530b57cec5SDimitry Andric                                            tok::TokenKind OpKind,
79540b57cec5SDimitry Andric                                            CXXScopeSpec &SS,
79550b57cec5SDimitry Andric                                            UnqualifiedId &FirstTypeName,
79560b57cec5SDimitry Andric                                            SourceLocation CCLoc,
79570b57cec5SDimitry Andric                                            SourceLocation TildeLoc,
79580b57cec5SDimitry Andric                                            UnqualifiedId &SecondTypeName) {
79590b57cec5SDimitry Andric   assert((FirstTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId ||
79600b57cec5SDimitry Andric           FirstTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) &&
79610b57cec5SDimitry Andric          "Invalid first type name in pseudo-destructor");
79620b57cec5SDimitry Andric   assert((SecondTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId ||
79630b57cec5SDimitry Andric           SecondTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) &&
79640b57cec5SDimitry Andric          "Invalid second type name in pseudo-destructor");
79650b57cec5SDimitry Andric 
79660b57cec5SDimitry Andric   QualType ObjectType;
79670b57cec5SDimitry Andric   if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
79680b57cec5SDimitry Andric     return ExprError();
79690b57cec5SDimitry Andric 
79700b57cec5SDimitry Andric   // Compute the object type that we should use for name lookup purposes. Only
79710b57cec5SDimitry Andric   // record types and dependent types matter.
79720b57cec5SDimitry Andric   ParsedType ObjectTypePtrForLookup;
79730b57cec5SDimitry Andric   if (!SS.isSet()) {
79740b57cec5SDimitry Andric     if (ObjectType->isRecordType())
79750b57cec5SDimitry Andric       ObjectTypePtrForLookup = ParsedType::make(ObjectType);
79760b57cec5SDimitry Andric     else if (ObjectType->isDependentType())
79770b57cec5SDimitry Andric       ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy);
79780b57cec5SDimitry Andric   }
79790b57cec5SDimitry Andric 
79800b57cec5SDimitry Andric   // Convert the name of the type being destructed (following the ~) into a
79810b57cec5SDimitry Andric   // type (with source-location information).
79820b57cec5SDimitry Andric   QualType DestructedType;
79830b57cec5SDimitry Andric   TypeSourceInfo *DestructedTypeInfo = nullptr;
79840b57cec5SDimitry Andric   PseudoDestructorTypeStorage Destructed;
79850b57cec5SDimitry Andric   if (SecondTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) {
79860b57cec5SDimitry Andric     ParsedType T = getTypeName(*SecondTypeName.Identifier,
79870b57cec5SDimitry Andric                                SecondTypeName.StartLocation,
79880b57cec5SDimitry Andric                                S, &SS, true, false, ObjectTypePtrForLookup,
79890b57cec5SDimitry Andric                                /*IsCtorOrDtorName*/true);
79900b57cec5SDimitry Andric     if (!T &&
79910b57cec5SDimitry Andric         ((SS.isSet() && !computeDeclContext(SS, false)) ||
79920b57cec5SDimitry Andric          (!SS.isSet() && ObjectType->isDependentType()))) {
79930b57cec5SDimitry Andric       // The name of the type being destroyed is a dependent name, and we
79940b57cec5SDimitry Andric       // couldn't find anything useful in scope. Just store the identifier and
79950b57cec5SDimitry Andric       // it's location, and we'll perform (qualified) name lookup again at
79960b57cec5SDimitry Andric       // template instantiation time.
79970b57cec5SDimitry Andric       Destructed = PseudoDestructorTypeStorage(SecondTypeName.Identifier,
79980b57cec5SDimitry Andric                                                SecondTypeName.StartLocation);
79990b57cec5SDimitry Andric     } else if (!T) {
80000b57cec5SDimitry Andric       Diag(SecondTypeName.StartLocation,
80010b57cec5SDimitry Andric            diag::err_pseudo_dtor_destructor_non_type)
80020b57cec5SDimitry Andric         << SecondTypeName.Identifier << ObjectType;
80030b57cec5SDimitry Andric       if (isSFINAEContext())
80040b57cec5SDimitry Andric         return ExprError();
80050b57cec5SDimitry Andric 
80060b57cec5SDimitry Andric       // Recover by assuming we had the right type all along.
80070b57cec5SDimitry Andric       DestructedType = ObjectType;
80080b57cec5SDimitry Andric     } else
80090b57cec5SDimitry Andric       DestructedType = GetTypeFromParser(T, &DestructedTypeInfo);
80100b57cec5SDimitry Andric   } else {
80110b57cec5SDimitry Andric     // Resolve the template-id to a type.
80120b57cec5SDimitry Andric     TemplateIdAnnotation *TemplateId = SecondTypeName.TemplateId;
80130b57cec5SDimitry Andric     ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
80140b57cec5SDimitry Andric                                        TemplateId->NumArgs);
80150b57cec5SDimitry Andric     TypeResult T = ActOnTemplateIdType(S,
801655e4f9d5SDimitry Andric                                        SS,
80170b57cec5SDimitry Andric                                        TemplateId->TemplateKWLoc,
80180b57cec5SDimitry Andric                                        TemplateId->Template,
80190b57cec5SDimitry Andric                                        TemplateId->Name,
80200b57cec5SDimitry Andric                                        TemplateId->TemplateNameLoc,
80210b57cec5SDimitry Andric                                        TemplateId->LAngleLoc,
80220b57cec5SDimitry Andric                                        TemplateArgsPtr,
80230b57cec5SDimitry Andric                                        TemplateId->RAngleLoc,
80240b57cec5SDimitry Andric                                        /*IsCtorOrDtorName*/true);
80250b57cec5SDimitry Andric     if (T.isInvalid() || !T.get()) {
80260b57cec5SDimitry Andric       // Recover by assuming we had the right type all along.
80270b57cec5SDimitry Andric       DestructedType = ObjectType;
80280b57cec5SDimitry Andric     } else
80290b57cec5SDimitry Andric       DestructedType = GetTypeFromParser(T.get(), &DestructedTypeInfo);
80300b57cec5SDimitry Andric   }
80310b57cec5SDimitry Andric 
80320b57cec5SDimitry Andric   // If we've performed some kind of recovery, (re-)build the type source
80330b57cec5SDimitry Andric   // information.
80340b57cec5SDimitry Andric   if (!DestructedType.isNull()) {
80350b57cec5SDimitry Andric     if (!DestructedTypeInfo)
80360b57cec5SDimitry Andric       DestructedTypeInfo = Context.getTrivialTypeSourceInfo(DestructedType,
80370b57cec5SDimitry Andric                                                   SecondTypeName.StartLocation);
80380b57cec5SDimitry Andric     Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
80390b57cec5SDimitry Andric   }
80400b57cec5SDimitry Andric 
80410b57cec5SDimitry Andric   // Convert the name of the scope type (the type prior to '::') into a type.
80420b57cec5SDimitry Andric   TypeSourceInfo *ScopeTypeInfo = nullptr;
80430b57cec5SDimitry Andric   QualType ScopeType;
80440b57cec5SDimitry Andric   if (FirstTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId ||
80450b57cec5SDimitry Andric       FirstTypeName.Identifier) {
80460b57cec5SDimitry Andric     if (FirstTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) {
80470b57cec5SDimitry Andric       ParsedType T = getTypeName(*FirstTypeName.Identifier,
80480b57cec5SDimitry Andric                                  FirstTypeName.StartLocation,
80490b57cec5SDimitry Andric                                  S, &SS, true, false, ObjectTypePtrForLookup,
80500b57cec5SDimitry Andric                                  /*IsCtorOrDtorName*/true);
80510b57cec5SDimitry Andric       if (!T) {
80520b57cec5SDimitry Andric         Diag(FirstTypeName.StartLocation,
80530b57cec5SDimitry Andric              diag::err_pseudo_dtor_destructor_non_type)
80540b57cec5SDimitry Andric           << FirstTypeName.Identifier << ObjectType;
80550b57cec5SDimitry Andric 
80560b57cec5SDimitry Andric         if (isSFINAEContext())
80570b57cec5SDimitry Andric           return ExprError();
80580b57cec5SDimitry Andric 
80590b57cec5SDimitry Andric         // Just drop this type. It's unnecessary anyway.
80600b57cec5SDimitry Andric         ScopeType = QualType();
80610b57cec5SDimitry Andric       } else
80620b57cec5SDimitry Andric         ScopeType = GetTypeFromParser(T, &ScopeTypeInfo);
80630b57cec5SDimitry Andric     } else {
80640b57cec5SDimitry Andric       // Resolve the template-id to a type.
80650b57cec5SDimitry Andric       TemplateIdAnnotation *TemplateId = FirstTypeName.TemplateId;
80660b57cec5SDimitry Andric       ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
80670b57cec5SDimitry Andric                                          TemplateId->NumArgs);
80680b57cec5SDimitry Andric       TypeResult T = ActOnTemplateIdType(S,
806955e4f9d5SDimitry Andric                                          SS,
80700b57cec5SDimitry Andric                                          TemplateId->TemplateKWLoc,
80710b57cec5SDimitry Andric                                          TemplateId->Template,
80720b57cec5SDimitry Andric                                          TemplateId->Name,
80730b57cec5SDimitry Andric                                          TemplateId->TemplateNameLoc,
80740b57cec5SDimitry Andric                                          TemplateId->LAngleLoc,
80750b57cec5SDimitry Andric                                          TemplateArgsPtr,
80760b57cec5SDimitry Andric                                          TemplateId->RAngleLoc,
80770b57cec5SDimitry Andric                                          /*IsCtorOrDtorName*/true);
80780b57cec5SDimitry Andric       if (T.isInvalid() || !T.get()) {
80790b57cec5SDimitry Andric         // Recover by dropping this type.
80800b57cec5SDimitry Andric         ScopeType = QualType();
80810b57cec5SDimitry Andric       } else
80820b57cec5SDimitry Andric         ScopeType = GetTypeFromParser(T.get(), &ScopeTypeInfo);
80830b57cec5SDimitry Andric     }
80840b57cec5SDimitry Andric   }
80850b57cec5SDimitry Andric 
80860b57cec5SDimitry Andric   if (!ScopeType.isNull() && !ScopeTypeInfo)
80870b57cec5SDimitry Andric     ScopeTypeInfo = Context.getTrivialTypeSourceInfo(ScopeType,
80880b57cec5SDimitry Andric                                                   FirstTypeName.StartLocation);
80890b57cec5SDimitry Andric 
80900b57cec5SDimitry Andric 
80910b57cec5SDimitry Andric   return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, SS,
80920b57cec5SDimitry Andric                                    ScopeTypeInfo, CCLoc, TildeLoc,
80930b57cec5SDimitry Andric                                    Destructed);
80940b57cec5SDimitry Andric }
80950b57cec5SDimitry Andric 
ActOnPseudoDestructorExpr(Scope * S,Expr * Base,SourceLocation OpLoc,tok::TokenKind OpKind,SourceLocation TildeLoc,const DeclSpec & DS)80960b57cec5SDimitry Andric ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
80970b57cec5SDimitry Andric                                            SourceLocation OpLoc,
80980b57cec5SDimitry Andric                                            tok::TokenKind OpKind,
80990b57cec5SDimitry Andric                                            SourceLocation TildeLoc,
81000b57cec5SDimitry Andric                                            const DeclSpec& DS) {
81010b57cec5SDimitry Andric   QualType ObjectType;
81020b57cec5SDimitry Andric   if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
81030b57cec5SDimitry Andric     return ExprError();
81040b57cec5SDimitry Andric 
8105e8d8bef9SDimitry Andric   if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto) {
8106e8d8bef9SDimitry Andric     Diag(DS.getTypeSpecTypeLoc(), diag::err_decltype_auto_invalid);
8107e8d8bef9SDimitry Andric     return true;
8108e8d8bef9SDimitry Andric   }
8109e8d8bef9SDimitry Andric 
8110349cc55cSDimitry Andric   QualType T = BuildDecltypeType(DS.getRepAsExpr(), /*AsUnevaluated=*/false);
81110b57cec5SDimitry Andric 
81120b57cec5SDimitry Andric   TypeLocBuilder TLB;
81130b57cec5SDimitry Andric   DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T);
811404eeddc0SDimitry Andric   DecltypeTL.setDecltypeLoc(DS.getTypeSpecTypeLoc());
811504eeddc0SDimitry Andric   DecltypeTL.setRParenLoc(DS.getTypeofParensRange().getEnd());
81160b57cec5SDimitry Andric   TypeSourceInfo *DestructedTypeInfo = TLB.getTypeSourceInfo(Context, T);
81170b57cec5SDimitry Andric   PseudoDestructorTypeStorage Destructed(DestructedTypeInfo);
81180b57cec5SDimitry Andric 
81190b57cec5SDimitry Andric   return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, CXXScopeSpec(),
81200b57cec5SDimitry Andric                                    nullptr, SourceLocation(), TildeLoc,
81210b57cec5SDimitry Andric                                    Destructed);
81220b57cec5SDimitry Andric }
81230b57cec5SDimitry Andric 
BuildCXXNoexceptExpr(SourceLocation KeyLoc,Expr * Operand,SourceLocation RParen)81240b57cec5SDimitry Andric ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
81250b57cec5SDimitry Andric                                       SourceLocation RParen) {
81260b57cec5SDimitry Andric   // If the operand is an unresolved lookup expression, the expression is ill-
81270b57cec5SDimitry Andric   // formed per [over.over]p1, because overloaded function names cannot be used
81280b57cec5SDimitry Andric   // without arguments except in explicit contexts.
81290b57cec5SDimitry Andric   ExprResult R = CheckPlaceholderExpr(Operand);
81300b57cec5SDimitry Andric   if (R.isInvalid())
81310b57cec5SDimitry Andric     return R;
81320b57cec5SDimitry Andric 
8133a7dea167SDimitry Andric   R = CheckUnevaluatedOperand(R.get());
8134a7dea167SDimitry Andric   if (R.isInvalid())
8135a7dea167SDimitry Andric     return ExprError();
8136a7dea167SDimitry Andric 
81370b57cec5SDimitry Andric   Operand = R.get();
81380b57cec5SDimitry Andric 
8139e8d8bef9SDimitry Andric   if (!inTemplateInstantiation() && !Operand->isInstantiationDependent() &&
8140e8d8bef9SDimitry Andric       Operand->HasSideEffects(Context, false)) {
81410b57cec5SDimitry Andric     // The expression operand for noexcept is in an unevaluated expression
81420b57cec5SDimitry Andric     // context, so side effects could result in unintended consequences.
81430b57cec5SDimitry Andric     Diag(Operand->getExprLoc(), diag::warn_side_effects_unevaluated_context);
81440b57cec5SDimitry Andric   }
81450b57cec5SDimitry Andric 
81460b57cec5SDimitry Andric   CanThrowResult CanThrow = canThrow(Operand);
81470b57cec5SDimitry Andric   return new (Context)
81480b57cec5SDimitry Andric       CXXNoexceptExpr(Context.BoolTy, Operand, CanThrow, KeyLoc, RParen);
81490b57cec5SDimitry Andric }
81500b57cec5SDimitry Andric 
ActOnNoexceptExpr(SourceLocation KeyLoc,SourceLocation,Expr * Operand,SourceLocation RParen)81510b57cec5SDimitry Andric ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation,
81520b57cec5SDimitry Andric                                    Expr *Operand, SourceLocation RParen) {
81530b57cec5SDimitry Andric   return BuildCXXNoexceptExpr(KeyLoc, Operand, RParen);
81540b57cec5SDimitry Andric }
81550b57cec5SDimitry Andric 
MaybeDecrementCount(Expr * E,llvm::DenseMap<const VarDecl *,int> & RefsMinusAssignments)8156fe6060f1SDimitry Andric static void MaybeDecrementCount(
8157fe6060f1SDimitry Andric     Expr *E, llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {
8158fe6060f1SDimitry Andric   DeclRefExpr *LHS = nullptr;
815981ad6265SDimitry Andric   bool IsCompoundAssign = false;
816081ad6265SDimitry Andric   bool isIncrementDecrementUnaryOp = false;
8161fe6060f1SDimitry Andric   if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
8162fe6060f1SDimitry Andric     if (BO->getLHS()->getType()->isDependentType() ||
8163fe6060f1SDimitry Andric         BO->getRHS()->getType()->isDependentType()) {
8164fe6060f1SDimitry Andric       if (BO->getOpcode() != BO_Assign)
8165fe6060f1SDimitry Andric         return;
8166fe6060f1SDimitry Andric     } else if (!BO->isAssignmentOp())
8167fe6060f1SDimitry Andric       return;
816881ad6265SDimitry Andric     else
816981ad6265SDimitry Andric       IsCompoundAssign = BO->isCompoundAssignmentOp();
8170fe6060f1SDimitry Andric     LHS = dyn_cast<DeclRefExpr>(BO->getLHS());
8171fe6060f1SDimitry Andric   } else if (CXXOperatorCallExpr *COCE = dyn_cast<CXXOperatorCallExpr>(E)) {
8172fe6060f1SDimitry Andric     if (COCE->getOperator() != OO_Equal)
8173fe6060f1SDimitry Andric       return;
8174fe6060f1SDimitry Andric     LHS = dyn_cast<DeclRefExpr>(COCE->getArg(0));
817581ad6265SDimitry Andric   } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
817681ad6265SDimitry Andric     if (!UO->isIncrementDecrementOp())
817781ad6265SDimitry Andric       return;
817881ad6265SDimitry Andric     isIncrementDecrementUnaryOp = true;
817981ad6265SDimitry Andric     LHS = dyn_cast<DeclRefExpr>(UO->getSubExpr());
8180fe6060f1SDimitry Andric   }
8181fe6060f1SDimitry Andric   if (!LHS)
8182fe6060f1SDimitry Andric     return;
8183fe6060f1SDimitry Andric   VarDecl *VD = dyn_cast<VarDecl>(LHS->getDecl());
8184fe6060f1SDimitry Andric   if (!VD)
8185fe6060f1SDimitry Andric     return;
818681ad6265SDimitry Andric   // Don't decrement RefsMinusAssignments if volatile variable with compound
818781ad6265SDimitry Andric   // assignment (+=, ...) or increment/decrement unary operator to avoid
818881ad6265SDimitry Andric   // potential unused-but-set-variable warning.
818981ad6265SDimitry Andric   if ((IsCompoundAssign || isIncrementDecrementUnaryOp) &&
819081ad6265SDimitry Andric       VD->getType().isVolatileQualified())
819181ad6265SDimitry Andric     return;
8192fe6060f1SDimitry Andric   auto iter = RefsMinusAssignments.find(VD);
8193fe6060f1SDimitry Andric   if (iter == RefsMinusAssignments.end())
8194fe6060f1SDimitry Andric     return;
8195fe6060f1SDimitry Andric   iter->getSecond()--;
8196fe6060f1SDimitry Andric }
8197fe6060f1SDimitry Andric 
81980b57cec5SDimitry Andric /// Perform the conversions required for an expression used in a
81990b57cec5SDimitry Andric /// context that ignores the result.
IgnoredValueConversions(Expr * E)82000b57cec5SDimitry Andric ExprResult Sema::IgnoredValueConversions(Expr *E) {
8201fe6060f1SDimitry Andric   MaybeDecrementCount(E, RefsMinusAssignments);
8202fe6060f1SDimitry Andric 
82030b57cec5SDimitry Andric   if (E->hasPlaceholderType()) {
82040b57cec5SDimitry Andric     ExprResult result = CheckPlaceholderExpr(E);
82050b57cec5SDimitry Andric     if (result.isInvalid()) return E;
82060b57cec5SDimitry Andric     E = result.get();
82070b57cec5SDimitry Andric   }
82080b57cec5SDimitry Andric 
82090b57cec5SDimitry Andric   // C99 6.3.2.1:
82100b57cec5SDimitry Andric   //   [Except in specific positions,] an lvalue that does not have
82110b57cec5SDimitry Andric   //   array type is converted to the value stored in the
82120b57cec5SDimitry Andric   //   designated object (and is no longer an lvalue).
8213fe6060f1SDimitry Andric   if (E->isPRValue()) {
82140b57cec5SDimitry Andric     // In C, function designators (i.e. expressions of function type)
82150b57cec5SDimitry Andric     // are r-values, but we still want to do function-to-pointer decay
82160b57cec5SDimitry Andric     // on them.  This is both technically correct and convenient for
82170b57cec5SDimitry Andric     // some clients.
82180b57cec5SDimitry Andric     if (!getLangOpts().CPlusPlus && E->getType()->isFunctionType())
82190b57cec5SDimitry Andric       return DefaultFunctionArrayConversion(E);
82200b57cec5SDimitry Andric 
82210b57cec5SDimitry Andric     return E;
82220b57cec5SDimitry Andric   }
82230b57cec5SDimitry Andric 
82240b57cec5SDimitry Andric   if (getLangOpts().CPlusPlus) {
82250b57cec5SDimitry Andric     // The C++11 standard defines the notion of a discarded-value expression;
82260b57cec5SDimitry Andric     // normally, we don't need to do anything to handle it, but if it is a
82270b57cec5SDimitry Andric     // volatile lvalue with a special form, we perform an lvalue-to-rvalue
82280b57cec5SDimitry Andric     // conversion.
82295ffd83dbSDimitry Andric     if (getLangOpts().CPlusPlus11 && E->isReadIfDiscardedInCPlusPlus11()) {
82300b57cec5SDimitry Andric       ExprResult Res = DefaultLvalueConversion(E);
82310b57cec5SDimitry Andric       if (Res.isInvalid())
82320b57cec5SDimitry Andric         return E;
82330b57cec5SDimitry Andric       E = Res.get();
8234a7dea167SDimitry Andric     } else {
8235a7dea167SDimitry Andric       // Per C++2a [expr.ass]p5, a volatile assignment is not deprecated if
8236a7dea167SDimitry Andric       // it occurs as a discarded-value expression.
8237a7dea167SDimitry Andric       CheckUnusedVolatileAssignment(E);
8238a7dea167SDimitry Andric     }
82390b57cec5SDimitry Andric 
82400b57cec5SDimitry Andric     // C++1z:
82410b57cec5SDimitry Andric     //   If the expression is a prvalue after this optional conversion, the
82420b57cec5SDimitry Andric     //   temporary materialization conversion is applied.
82430b57cec5SDimitry Andric     //
82440b57cec5SDimitry Andric     // We skip this step: IR generation is able to synthesize the storage for
82450b57cec5SDimitry Andric     // itself in the aggregate case, and adding the extra node to the AST is
82460b57cec5SDimitry Andric     // just clutter.
82470b57cec5SDimitry Andric     // FIXME: We don't emit lifetime markers for the temporaries due to this.
82480b57cec5SDimitry Andric     // FIXME: Do any other AST consumers care about this?
82490b57cec5SDimitry Andric     return E;
82500b57cec5SDimitry Andric   }
82510b57cec5SDimitry Andric 
82520b57cec5SDimitry Andric   // GCC seems to also exclude expressions of incomplete enum type.
82530b57cec5SDimitry Andric   if (const EnumType *T = E->getType()->getAs<EnumType>()) {
82540b57cec5SDimitry Andric     if (!T->getDecl()->isComplete()) {
82550b57cec5SDimitry Andric       // FIXME: stupid workaround for a codegen bug!
82560b57cec5SDimitry Andric       E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get();
82570b57cec5SDimitry Andric       return E;
82580b57cec5SDimitry Andric     }
82590b57cec5SDimitry Andric   }
82600b57cec5SDimitry Andric 
82610b57cec5SDimitry Andric   ExprResult Res = DefaultFunctionArrayLvalueConversion(E);
82620b57cec5SDimitry Andric   if (Res.isInvalid())
82630b57cec5SDimitry Andric     return E;
82640b57cec5SDimitry Andric   E = Res.get();
82650b57cec5SDimitry Andric 
82660b57cec5SDimitry Andric   if (!E->getType()->isVoidType())
82670b57cec5SDimitry Andric     RequireCompleteType(E->getExprLoc(), E->getType(),
82680b57cec5SDimitry Andric                         diag::err_incomplete_type);
82690b57cec5SDimitry Andric   return E;
82700b57cec5SDimitry Andric }
82710b57cec5SDimitry Andric 
CheckUnevaluatedOperand(Expr * E)8272a7dea167SDimitry Andric ExprResult Sema::CheckUnevaluatedOperand(Expr *E) {
8273a7dea167SDimitry Andric   // Per C++2a [expr.ass]p5, a volatile assignment is not deprecated if
8274a7dea167SDimitry Andric   // it occurs as an unevaluated operand.
8275a7dea167SDimitry Andric   CheckUnusedVolatileAssignment(E);
8276a7dea167SDimitry Andric 
8277a7dea167SDimitry Andric   return E;
8278a7dea167SDimitry Andric }
8279a7dea167SDimitry Andric 
82800b57cec5SDimitry Andric // If we can unambiguously determine whether Var can never be used
82810b57cec5SDimitry Andric // in a constant expression, return true.
82820b57cec5SDimitry Andric //  - if the variable and its initializer are non-dependent, then
82830b57cec5SDimitry Andric //    we can unambiguously check if the variable is a constant expression.
82840b57cec5SDimitry Andric //  - if the initializer is not value dependent - we can determine whether
82850b57cec5SDimitry Andric //    it can be used to initialize a constant expression.  If Init can not
82860b57cec5SDimitry Andric //    be used to initialize a constant expression we conclude that Var can
82870b57cec5SDimitry Andric //    never be a constant expression.
82880b57cec5SDimitry Andric //  - FXIME: if the initializer is dependent, we can still do some analysis and
82890b57cec5SDimitry Andric //    identify certain cases unambiguously as non-const by using a Visitor:
82900b57cec5SDimitry Andric //      - such as those that involve odr-use of a ParmVarDecl, involve a new
82910b57cec5SDimitry Andric //        delete, lambda-expr, dynamic-cast, reinterpret-cast etc...
VariableCanNeverBeAConstantExpression(VarDecl * Var,ASTContext & Context)82920b57cec5SDimitry Andric static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var,
82930b57cec5SDimitry Andric     ASTContext &Context) {
82940b57cec5SDimitry Andric   if (isa<ParmVarDecl>(Var)) return true;
82950b57cec5SDimitry Andric   const VarDecl *DefVD = nullptr;
82960b57cec5SDimitry Andric 
82970b57cec5SDimitry Andric   // If there is no initializer - this can not be a constant expression.
829806c3fb27SDimitry Andric   const Expr *Init = Var->getAnyInitializer(DefVD);
829906c3fb27SDimitry Andric   if (!Init)
830006c3fb27SDimitry Andric     return true;
83010b57cec5SDimitry Andric   assert(DefVD);
830206c3fb27SDimitry Andric   if (DefVD->isWeak())
830306c3fb27SDimitry Andric     return false;
83040b57cec5SDimitry Andric 
83050b57cec5SDimitry Andric   if (Var->getType()->isDependentType() || Init->isValueDependent()) {
83060b57cec5SDimitry Andric     // FIXME: Teach the constant evaluator to deal with the non-dependent parts
83070b57cec5SDimitry Andric     // of value-dependent expressions, and use it here to determine whether the
83080b57cec5SDimitry Andric     // initializer is a potential constant expression.
83090b57cec5SDimitry Andric     return false;
83100b57cec5SDimitry Andric   }
83110b57cec5SDimitry Andric 
83120b57cec5SDimitry Andric   return !Var->isUsableInConstantExpressions(Context);
83130b57cec5SDimitry Andric }
83140b57cec5SDimitry Andric 
83150b57cec5SDimitry Andric /// Check if the current lambda has any potential captures
83160b57cec5SDimitry Andric /// that must be captured by any of its enclosing lambdas that are ready to
83170b57cec5SDimitry Andric /// capture. If there is a lambda that can capture a nested
83180b57cec5SDimitry Andric /// potential-capture, go ahead and do so.  Also, check to see if any
83190b57cec5SDimitry Andric /// variables are uncaptureable or do not involve an odr-use so do not
83200b57cec5SDimitry Andric /// need to be captured.
83210b57cec5SDimitry Andric 
CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(Expr * const FE,LambdaScopeInfo * const CurrentLSI,Sema & S)83220b57cec5SDimitry Andric static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
83230b57cec5SDimitry Andric     Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S) {
83240b57cec5SDimitry Andric 
83250b57cec5SDimitry Andric   assert(!S.isUnevaluatedContext());
83260b57cec5SDimitry Andric   assert(S.CurContext->isDependentContext());
83270b57cec5SDimitry Andric #ifndef NDEBUG
83280b57cec5SDimitry Andric   DeclContext *DC = S.CurContext;
83290b57cec5SDimitry Andric   while (DC && isa<CapturedDecl>(DC))
83300b57cec5SDimitry Andric     DC = DC->getParent();
83310b57cec5SDimitry Andric   assert(
83320b57cec5SDimitry Andric       CurrentLSI->CallOperator == DC &&
83330b57cec5SDimitry Andric       "The current call operator must be synchronized with Sema's CurContext");
83340b57cec5SDimitry Andric #endif // NDEBUG
83350b57cec5SDimitry Andric 
83360b57cec5SDimitry Andric   const bool IsFullExprInstantiationDependent = FE->isInstantiationDependent();
83370b57cec5SDimitry Andric 
83380b57cec5SDimitry Andric   // All the potentially captureable variables in the current nested
83390b57cec5SDimitry Andric   // lambda (within a generic outer lambda), must be captured by an
83400b57cec5SDimitry Andric   // outer lambda that is enclosed within a non-dependent context.
8341bdd1243dSDimitry Andric   CurrentLSI->visitPotentialCaptures([&](ValueDecl *Var, Expr *VarExpr) {
83420b57cec5SDimitry Andric     // If the variable is clearly identified as non-odr-used and the full
83430b57cec5SDimitry Andric     // expression is not instantiation dependent, only then do we not
83440b57cec5SDimitry Andric     // need to check enclosing lambda's for speculative captures.
83450b57cec5SDimitry Andric     // For e.g.:
83460b57cec5SDimitry Andric     // Even though 'x' is not odr-used, it should be captured.
83470b57cec5SDimitry Andric     // int test() {
83480b57cec5SDimitry Andric     //   const int x = 10;
83490b57cec5SDimitry Andric     //   auto L = [=](auto a) {
83500b57cec5SDimitry Andric     //     (void) +x + a;
83510b57cec5SDimitry Andric     //   };
83520b57cec5SDimitry Andric     // }
83530b57cec5SDimitry Andric     if (CurrentLSI->isVariableExprMarkedAsNonODRUsed(VarExpr) &&
83540b57cec5SDimitry Andric         !IsFullExprInstantiationDependent)
83550b57cec5SDimitry Andric       return;
83560b57cec5SDimitry Andric 
8357bdd1243dSDimitry Andric     VarDecl *UnderlyingVar = Var->getPotentiallyDecomposedVarDecl();
8358bdd1243dSDimitry Andric     if (!UnderlyingVar)
8359bdd1243dSDimitry Andric       return;
8360bdd1243dSDimitry Andric 
83610b57cec5SDimitry Andric     // If we have a capture-capable lambda for the variable, go ahead and
83620b57cec5SDimitry Andric     // capture the variable in that lambda (and all its enclosing lambdas).
8363bdd1243dSDimitry Andric     if (const std::optional<unsigned> Index =
83640b57cec5SDimitry Andric             getStackIndexOfNearestEnclosingCaptureCapableLambda(
83650b57cec5SDimitry Andric                 S.FunctionScopes, Var, S))
836681ad6265SDimitry Andric       S.MarkCaptureUsedInEnclosingContext(Var, VarExpr->getExprLoc(), *Index);
83670b57cec5SDimitry Andric     const bool IsVarNeverAConstantExpression =
8368bdd1243dSDimitry Andric         VariableCanNeverBeAConstantExpression(UnderlyingVar, S.Context);
83690b57cec5SDimitry Andric     if (!IsFullExprInstantiationDependent || IsVarNeverAConstantExpression) {
83700b57cec5SDimitry Andric       // This full expression is not instantiation dependent or the variable
83710b57cec5SDimitry Andric       // can not be used in a constant expression - which means
83720b57cec5SDimitry Andric       // this variable must be odr-used here, so diagnose a
83730b57cec5SDimitry Andric       // capture violation early, if the variable is un-captureable.
83740b57cec5SDimitry Andric       // This is purely for diagnosing errors early.  Otherwise, this
83750b57cec5SDimitry Andric       // error would get diagnosed when the lambda becomes capture ready.
83760b57cec5SDimitry Andric       QualType CaptureType, DeclRefType;
83770b57cec5SDimitry Andric       SourceLocation ExprLoc = VarExpr->getExprLoc();
83780b57cec5SDimitry Andric       if (S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit,
83790b57cec5SDimitry Andric                           /*EllipsisLoc*/ SourceLocation(),
83800b57cec5SDimitry Andric                           /*BuildAndDiagnose*/false, CaptureType,
83810b57cec5SDimitry Andric                           DeclRefType, nullptr)) {
83820b57cec5SDimitry Andric         // We will never be able to capture this variable, and we need
83830b57cec5SDimitry Andric         // to be able to in any and all instantiations, so diagnose it.
83840b57cec5SDimitry Andric         S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit,
83850b57cec5SDimitry Andric                           /*EllipsisLoc*/ SourceLocation(),
83860b57cec5SDimitry Andric                           /*BuildAndDiagnose*/true, CaptureType,
83870b57cec5SDimitry Andric                           DeclRefType, nullptr);
83880b57cec5SDimitry Andric       }
83890b57cec5SDimitry Andric     }
83900b57cec5SDimitry Andric   });
83910b57cec5SDimitry Andric 
83920b57cec5SDimitry Andric   // Check if 'this' needs to be captured.
83930b57cec5SDimitry Andric   if (CurrentLSI->hasPotentialThisCapture()) {
83940b57cec5SDimitry Andric     // If we have a capture-capable lambda for 'this', go ahead and capture
83950b57cec5SDimitry Andric     // 'this' in that lambda (and all its enclosing lambdas).
8396bdd1243dSDimitry Andric     if (const std::optional<unsigned> Index =
83970b57cec5SDimitry Andric             getStackIndexOfNearestEnclosingCaptureCapableLambda(
83980b57cec5SDimitry Andric                 S.FunctionScopes, /*0 is 'this'*/ nullptr, S)) {
839981ad6265SDimitry Andric       const unsigned FunctionScopeIndexOfCapturableLambda = *Index;
84000b57cec5SDimitry Andric       S.CheckCXXThisCapture(CurrentLSI->PotentialThisCaptureLocation,
84010b57cec5SDimitry Andric                             /*Explicit*/ false, /*BuildAndDiagnose*/ true,
84020b57cec5SDimitry Andric                             &FunctionScopeIndexOfCapturableLambda);
84030b57cec5SDimitry Andric     }
84040b57cec5SDimitry Andric   }
84050b57cec5SDimitry Andric 
84060b57cec5SDimitry Andric   // Reset all the potential captures at the end of each full-expression.
84070b57cec5SDimitry Andric   CurrentLSI->clearPotentialCaptures();
84080b57cec5SDimitry Andric }
84090b57cec5SDimitry Andric 
attemptRecovery(Sema & SemaRef,const TypoCorrectionConsumer & Consumer,const TypoCorrection & TC)84100b57cec5SDimitry Andric static ExprResult attemptRecovery(Sema &SemaRef,
84110b57cec5SDimitry Andric                                   const TypoCorrectionConsumer &Consumer,
84120b57cec5SDimitry Andric                                   const TypoCorrection &TC) {
84130b57cec5SDimitry Andric   LookupResult R(SemaRef, Consumer.getLookupResult().getLookupNameInfo(),
84140b57cec5SDimitry Andric                  Consumer.getLookupResult().getLookupKind());
84150b57cec5SDimitry Andric   const CXXScopeSpec *SS = Consumer.getSS();
84160b57cec5SDimitry Andric   CXXScopeSpec NewSS;
84170b57cec5SDimitry Andric 
84180b57cec5SDimitry Andric   // Use an approprate CXXScopeSpec for building the expr.
84190b57cec5SDimitry Andric   if (auto *NNS = TC.getCorrectionSpecifier())
84200b57cec5SDimitry Andric     NewSS.MakeTrivial(SemaRef.Context, NNS, TC.getCorrectionRange());
84210b57cec5SDimitry Andric   else if (SS && !TC.WillReplaceSpecifier())
84220b57cec5SDimitry Andric     NewSS = *SS;
84230b57cec5SDimitry Andric 
84240b57cec5SDimitry Andric   if (auto *ND = TC.getFoundDecl()) {
84250b57cec5SDimitry Andric     R.setLookupName(ND->getDeclName());
84260b57cec5SDimitry Andric     R.addDecl(ND);
84270b57cec5SDimitry Andric     if (ND->isCXXClassMember()) {
84280b57cec5SDimitry Andric       // Figure out the correct naming class to add to the LookupResult.
84290b57cec5SDimitry Andric       CXXRecordDecl *Record = nullptr;
84300b57cec5SDimitry Andric       if (auto *NNS = TC.getCorrectionSpecifier())
84310b57cec5SDimitry Andric         Record = NNS->getAsType()->getAsCXXRecordDecl();
84320b57cec5SDimitry Andric       if (!Record)
84330b57cec5SDimitry Andric         Record =
84340b57cec5SDimitry Andric             dyn_cast<CXXRecordDecl>(ND->getDeclContext()->getRedeclContext());
84350b57cec5SDimitry Andric       if (Record)
84360b57cec5SDimitry Andric         R.setNamingClass(Record);
84370b57cec5SDimitry Andric 
84380b57cec5SDimitry Andric       // Detect and handle the case where the decl might be an implicit
84390b57cec5SDimitry Andric       // member.
84400b57cec5SDimitry Andric       bool MightBeImplicitMember;
84410b57cec5SDimitry Andric       if (!Consumer.isAddressOfOperand())
84420b57cec5SDimitry Andric         MightBeImplicitMember = true;
84430b57cec5SDimitry Andric       else if (!NewSS.isEmpty())
84440b57cec5SDimitry Andric         MightBeImplicitMember = false;
84450b57cec5SDimitry Andric       else if (R.isOverloadedResult())
84460b57cec5SDimitry Andric         MightBeImplicitMember = false;
84470b57cec5SDimitry Andric       else if (R.isUnresolvableResult())
84480b57cec5SDimitry Andric         MightBeImplicitMember = true;
84490b57cec5SDimitry Andric       else
84500b57cec5SDimitry Andric         MightBeImplicitMember = isa<FieldDecl>(ND) ||
84510b57cec5SDimitry Andric                                 isa<IndirectFieldDecl>(ND) ||
84520b57cec5SDimitry Andric                                 isa<MSPropertyDecl>(ND);
84530b57cec5SDimitry Andric 
84540b57cec5SDimitry Andric       if (MightBeImplicitMember)
84550b57cec5SDimitry Andric         return SemaRef.BuildPossibleImplicitMemberExpr(
84560b57cec5SDimitry Andric             NewSS, /*TemplateKWLoc*/ SourceLocation(), R,
84570b57cec5SDimitry Andric             /*TemplateArgs*/ nullptr, /*S*/ nullptr);
84580b57cec5SDimitry Andric     } else if (auto *Ivar = dyn_cast<ObjCIvarDecl>(ND)) {
84590b57cec5SDimitry Andric       return SemaRef.LookupInObjCMethod(R, Consumer.getScope(),
84600b57cec5SDimitry Andric                                         Ivar->getIdentifier());
84610b57cec5SDimitry Andric     }
84620b57cec5SDimitry Andric   }
84630b57cec5SDimitry Andric 
84640b57cec5SDimitry Andric   return SemaRef.BuildDeclarationNameExpr(NewSS, R, /*NeedsADL*/ false,
84650b57cec5SDimitry Andric                                           /*AcceptInvalidDecl*/ true);
84660b57cec5SDimitry Andric }
84670b57cec5SDimitry Andric 
84680b57cec5SDimitry Andric namespace {
84690b57cec5SDimitry Andric class FindTypoExprs : public RecursiveASTVisitor<FindTypoExprs> {
84700b57cec5SDimitry Andric   llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs;
84710b57cec5SDimitry Andric 
84720b57cec5SDimitry Andric public:
FindTypoExprs(llvm::SmallSetVector<TypoExpr *,2> & TypoExprs)84730b57cec5SDimitry Andric   explicit FindTypoExprs(llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs)
84740b57cec5SDimitry Andric       : TypoExprs(TypoExprs) {}
VisitTypoExpr(TypoExpr * TE)84750b57cec5SDimitry Andric   bool VisitTypoExpr(TypoExpr *TE) {
84760b57cec5SDimitry Andric     TypoExprs.insert(TE);
84770b57cec5SDimitry Andric     return true;
84780b57cec5SDimitry Andric   }
84790b57cec5SDimitry Andric };
84800b57cec5SDimitry Andric 
84810b57cec5SDimitry Andric class TransformTypos : public TreeTransform<TransformTypos> {
84820b57cec5SDimitry Andric   typedef TreeTransform<TransformTypos> BaseTransform;
84830b57cec5SDimitry Andric 
84840b57cec5SDimitry Andric   VarDecl *InitDecl; // A decl to avoid as a correction because it is in the
84850b57cec5SDimitry Andric                      // process of being initialized.
84860b57cec5SDimitry Andric   llvm::function_ref<ExprResult(Expr *)> ExprFilter;
84870b57cec5SDimitry Andric   llvm::SmallSetVector<TypoExpr *, 2> TypoExprs, AmbiguousTypoExprs;
84880b57cec5SDimitry Andric   llvm::SmallDenseMap<TypoExpr *, ExprResult, 2> TransformCache;
84890b57cec5SDimitry Andric   llvm::SmallDenseMap<OverloadExpr *, Expr *, 4> OverloadResolution;
84900b57cec5SDimitry Andric 
84910b57cec5SDimitry Andric   /// Emit diagnostics for all of the TypoExprs encountered.
8492a7dea167SDimitry Andric   ///
84930b57cec5SDimitry Andric   /// If the TypoExprs were successfully corrected, then the diagnostics should
84940b57cec5SDimitry Andric   /// suggest the corrections. Otherwise the diagnostics will not suggest
84950b57cec5SDimitry Andric   /// anything (having been passed an empty TypoCorrection).
8496a7dea167SDimitry Andric   ///
8497a7dea167SDimitry Andric   /// If we've failed to correct due to ambiguous corrections, we need to
8498a7dea167SDimitry Andric   /// be sure to pass empty corrections and replacements. Otherwise it's
8499a7dea167SDimitry Andric   /// possible that the Consumer has a TypoCorrection that failed to ambiguity
8500a7dea167SDimitry Andric   /// and we don't want to report those diagnostics.
EmitAllDiagnostics(bool IsAmbiguous)8501a7dea167SDimitry Andric   void EmitAllDiagnostics(bool IsAmbiguous) {
85020b57cec5SDimitry Andric     for (TypoExpr *TE : TypoExprs) {
85030b57cec5SDimitry Andric       auto &State = SemaRef.getTypoExprState(TE);
85040b57cec5SDimitry Andric       if (State.DiagHandler) {
8505a7dea167SDimitry Andric         TypoCorrection TC = IsAmbiguous
8506a7dea167SDimitry Andric             ? TypoCorrection() : State.Consumer->getCurrentCorrection();
8507a7dea167SDimitry Andric         ExprResult Replacement = IsAmbiguous ? ExprError() : TransformCache[TE];
85080b57cec5SDimitry Andric 
85090b57cec5SDimitry Andric         // Extract the NamedDecl from the transformed TypoExpr and add it to the
85100b57cec5SDimitry Andric         // TypoCorrection, replacing the existing decls. This ensures the right
85110b57cec5SDimitry Andric         // NamedDecl is used in diagnostics e.g. in the case where overload
85120b57cec5SDimitry Andric         // resolution was used to select one from several possible decls that
85130b57cec5SDimitry Andric         // had been stored in the TypoCorrection.
85140b57cec5SDimitry Andric         if (auto *ND = getDeclFromExpr(
85150b57cec5SDimitry Andric                 Replacement.isInvalid() ? nullptr : Replacement.get()))
85160b57cec5SDimitry Andric           TC.setCorrectionDecl(ND);
85170b57cec5SDimitry Andric 
85180b57cec5SDimitry Andric         State.DiagHandler(TC);
85190b57cec5SDimitry Andric       }
85200b57cec5SDimitry Andric       SemaRef.clearDelayedTypo(TE);
85210b57cec5SDimitry Andric     }
85220b57cec5SDimitry Andric   }
85230b57cec5SDimitry Andric 
8524590d96feSDimitry Andric   /// Try to advance the typo correction state of the first unfinished TypoExpr.
8525590d96feSDimitry Andric   /// We allow advancement of the correction stream by removing it from the
8526590d96feSDimitry Andric   /// TransformCache which allows `TransformTypoExpr` to advance during the
8527590d96feSDimitry Andric   /// next transformation attempt.
8528590d96feSDimitry Andric   ///
8529590d96feSDimitry Andric   /// Any substitution attempts for the previous TypoExprs (which must have been
8530590d96feSDimitry Andric   /// finished) will need to be retried since it's possible that they will now
8531590d96feSDimitry Andric   /// be invalid given the latest advancement.
8532590d96feSDimitry Andric   ///
8533590d96feSDimitry Andric   /// We need to be sure that we're making progress - it's possible that the
8534590d96feSDimitry Andric   /// tree is so malformed that the transform never makes it to the
8535590d96feSDimitry Andric   /// `TransformTypoExpr`.
8536590d96feSDimitry Andric   ///
8537590d96feSDimitry Andric   /// Returns true if there are any untried correction combinations.
CheckAndAdvanceTypoExprCorrectionStreams()85380b57cec5SDimitry Andric   bool CheckAndAdvanceTypoExprCorrectionStreams() {
8539bdd1243dSDimitry Andric     for (auto *TE : TypoExprs) {
85400b57cec5SDimitry Andric       auto &State = SemaRef.getTypoExprState(TE);
85410b57cec5SDimitry Andric       TransformCache.erase(TE);
8542590d96feSDimitry Andric       if (!State.Consumer->hasMadeAnyCorrectionProgress())
8543590d96feSDimitry Andric         return false;
85440b57cec5SDimitry Andric       if (!State.Consumer->finished())
85450b57cec5SDimitry Andric         return true;
85460b57cec5SDimitry Andric       State.Consumer->resetCorrectionStream();
85470b57cec5SDimitry Andric     }
85480b57cec5SDimitry Andric     return false;
85490b57cec5SDimitry Andric   }
85500b57cec5SDimitry Andric 
getDeclFromExpr(Expr * E)85510b57cec5SDimitry Andric   NamedDecl *getDeclFromExpr(Expr *E) {
85520b57cec5SDimitry Andric     if (auto *OE = dyn_cast_or_null<OverloadExpr>(E))
85530b57cec5SDimitry Andric       E = OverloadResolution[OE];
85540b57cec5SDimitry Andric 
85550b57cec5SDimitry Andric     if (!E)
85560b57cec5SDimitry Andric       return nullptr;
85570b57cec5SDimitry Andric     if (auto *DRE = dyn_cast<DeclRefExpr>(E))
85580b57cec5SDimitry Andric       return DRE->getFoundDecl();
85590b57cec5SDimitry Andric     if (auto *ME = dyn_cast<MemberExpr>(E))
85600b57cec5SDimitry Andric       return ME->getFoundDecl();
8561bdd1243dSDimitry Andric     // FIXME: Add any other expr types that could be seen by the delayed typo
85620b57cec5SDimitry Andric     // correction TreeTransform for which the corresponding TypoCorrection could
85630b57cec5SDimitry Andric     // contain multiple decls.
85640b57cec5SDimitry Andric     return nullptr;
85650b57cec5SDimitry Andric   }
85660b57cec5SDimitry Andric 
TryTransform(Expr * E)85670b57cec5SDimitry Andric   ExprResult TryTransform(Expr *E) {
85680b57cec5SDimitry Andric     Sema::SFINAETrap Trap(SemaRef);
85690b57cec5SDimitry Andric     ExprResult Res = TransformExpr(E);
85700b57cec5SDimitry Andric     if (Trap.hasErrorOccurred() || Res.isInvalid())
85710b57cec5SDimitry Andric       return ExprError();
85720b57cec5SDimitry Andric 
85730b57cec5SDimitry Andric     return ExprFilter(Res.get());
85740b57cec5SDimitry Andric   }
85750b57cec5SDimitry Andric 
8576a7dea167SDimitry Andric   // Since correcting typos may intoduce new TypoExprs, this function
8577a7dea167SDimitry Andric   // checks for new TypoExprs and recurses if it finds any. Note that it will
8578a7dea167SDimitry Andric   // only succeed if it is able to correct all typos in the given expression.
CheckForRecursiveTypos(ExprResult Res,bool & IsAmbiguous)8579a7dea167SDimitry Andric   ExprResult CheckForRecursiveTypos(ExprResult Res, bool &IsAmbiguous) {
8580a7dea167SDimitry Andric     if (Res.isInvalid()) {
8581a7dea167SDimitry Andric       return Res;
8582a7dea167SDimitry Andric     }
8583a7dea167SDimitry Andric     // Check to see if any new TypoExprs were created. If so, we need to recurse
8584a7dea167SDimitry Andric     // to check their validity.
8585a7dea167SDimitry Andric     Expr *FixedExpr = Res.get();
8586a7dea167SDimitry Andric 
8587a7dea167SDimitry Andric     auto SavedTypoExprs = std::move(TypoExprs);
8588a7dea167SDimitry Andric     auto SavedAmbiguousTypoExprs = std::move(AmbiguousTypoExprs);
8589a7dea167SDimitry Andric     TypoExprs.clear();
8590a7dea167SDimitry Andric     AmbiguousTypoExprs.clear();
8591a7dea167SDimitry Andric 
8592a7dea167SDimitry Andric     FindTypoExprs(TypoExprs).TraverseStmt(FixedExpr);
8593a7dea167SDimitry Andric     if (!TypoExprs.empty()) {
8594a7dea167SDimitry Andric       // Recurse to handle newly created TypoExprs. If we're not able to
8595a7dea167SDimitry Andric       // handle them, discard these TypoExprs.
8596a7dea167SDimitry Andric       ExprResult RecurResult =
8597a7dea167SDimitry Andric           RecursiveTransformLoop(FixedExpr, IsAmbiguous);
8598a7dea167SDimitry Andric       if (RecurResult.isInvalid()) {
8599a7dea167SDimitry Andric         Res = ExprError();
8600a7dea167SDimitry Andric         // Recursive corrections didn't work, wipe them away and don't add
8601a7dea167SDimitry Andric         // them to the TypoExprs set. Remove them from Sema's TypoExpr list
8602a7dea167SDimitry Andric         // since we don't want to clear them twice. Note: it's possible the
8603a7dea167SDimitry Andric         // TypoExprs were created recursively and thus won't be in our
8604a7dea167SDimitry Andric         // Sema's TypoExprs - they were created in our `RecursiveTransformLoop`.
8605a7dea167SDimitry Andric         auto &SemaTypoExprs = SemaRef.TypoExprs;
8606bdd1243dSDimitry Andric         for (auto *TE : TypoExprs) {
8607a7dea167SDimitry Andric           TransformCache.erase(TE);
8608a7dea167SDimitry Andric           SemaRef.clearDelayedTypo(TE);
8609a7dea167SDimitry Andric 
8610a7dea167SDimitry Andric           auto SI = find(SemaTypoExprs, TE);
8611a7dea167SDimitry Andric           if (SI != SemaTypoExprs.end()) {
8612a7dea167SDimitry Andric             SemaTypoExprs.erase(SI);
8613a7dea167SDimitry Andric           }
8614a7dea167SDimitry Andric         }
8615a7dea167SDimitry Andric       } else {
8616a7dea167SDimitry Andric         // TypoExpr is valid: add newly created TypoExprs since we were
8617a7dea167SDimitry Andric         // able to correct them.
8618a7dea167SDimitry Andric         Res = RecurResult;
8619a7dea167SDimitry Andric         SavedTypoExprs.set_union(TypoExprs);
8620a7dea167SDimitry Andric       }
8621a7dea167SDimitry Andric     }
8622a7dea167SDimitry Andric 
8623a7dea167SDimitry Andric     TypoExprs = std::move(SavedTypoExprs);
8624a7dea167SDimitry Andric     AmbiguousTypoExprs = std::move(SavedAmbiguousTypoExprs);
8625a7dea167SDimitry Andric 
8626a7dea167SDimitry Andric     return Res;
8627a7dea167SDimitry Andric   }
8628a7dea167SDimitry Andric 
8629a7dea167SDimitry Andric   // Try to transform the given expression, looping through the correction
8630a7dea167SDimitry Andric   // candidates with `CheckAndAdvanceTypoExprCorrectionStreams`.
8631a7dea167SDimitry Andric   //
8632a7dea167SDimitry Andric   // If valid ambiguous typo corrections are seen, `IsAmbiguous` is set to
8633a7dea167SDimitry Andric   // true and this method immediately will return an `ExprError`.
RecursiveTransformLoop(Expr * E,bool & IsAmbiguous)8634a7dea167SDimitry Andric   ExprResult RecursiveTransformLoop(Expr *E, bool &IsAmbiguous) {
8635a7dea167SDimitry Andric     ExprResult Res;
8636a7dea167SDimitry Andric     auto SavedTypoExprs = std::move(SemaRef.TypoExprs);
8637a7dea167SDimitry Andric     SemaRef.TypoExprs.clear();
8638a7dea167SDimitry Andric 
8639a7dea167SDimitry Andric     while (true) {
8640a7dea167SDimitry Andric       Res = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous);
8641a7dea167SDimitry Andric 
8642a7dea167SDimitry Andric       // Recursion encountered an ambiguous correction. This means that our
8643a7dea167SDimitry Andric       // correction itself is ambiguous, so stop now.
8644a7dea167SDimitry Andric       if (IsAmbiguous)
8645a7dea167SDimitry Andric         break;
8646a7dea167SDimitry Andric 
8647a7dea167SDimitry Andric       // If the transform is still valid after checking for any new typos,
8648a7dea167SDimitry Andric       // it's good to go.
8649a7dea167SDimitry Andric       if (!Res.isInvalid())
8650a7dea167SDimitry Andric         break;
8651a7dea167SDimitry Andric 
8652a7dea167SDimitry Andric       // The transform was invalid, see if we have any TypoExprs with untried
8653a7dea167SDimitry Andric       // correction candidates.
8654a7dea167SDimitry Andric       if (!CheckAndAdvanceTypoExprCorrectionStreams())
8655a7dea167SDimitry Andric         break;
8656a7dea167SDimitry Andric     }
8657a7dea167SDimitry Andric 
8658a7dea167SDimitry Andric     // If we found a valid result, double check to make sure it's not ambiguous.
8659a7dea167SDimitry Andric     if (!IsAmbiguous && !Res.isInvalid() && !AmbiguousTypoExprs.empty()) {
8660480093f4SDimitry Andric       auto SavedTransformCache =
8661480093f4SDimitry Andric           llvm::SmallDenseMap<TypoExpr *, ExprResult, 2>(TransformCache);
8662480093f4SDimitry Andric 
8663a7dea167SDimitry Andric       // Ensure none of the TypoExprs have multiple typo correction candidates
8664a7dea167SDimitry Andric       // with the same edit length that pass all the checks and filters.
8665a7dea167SDimitry Andric       while (!AmbiguousTypoExprs.empty()) {
8666a7dea167SDimitry Andric         auto TE  = AmbiguousTypoExprs.back();
8667a7dea167SDimitry Andric 
8668a7dea167SDimitry Andric         // TryTransform itself can create new Typos, adding them to the TypoExpr map
8669a7dea167SDimitry Andric         // and invalidating our TypoExprState, so always fetch it instead of storing.
8670a7dea167SDimitry Andric         SemaRef.getTypoExprState(TE).Consumer->saveCurrentPosition();
8671a7dea167SDimitry Andric 
8672a7dea167SDimitry Andric         TypoCorrection TC = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection();
8673a7dea167SDimitry Andric         TypoCorrection Next;
8674a7dea167SDimitry Andric         do {
8675a7dea167SDimitry Andric           // Fetch the next correction by erasing the typo from the cache and calling
8676a7dea167SDimitry Andric           // `TryTransform` which will iterate through corrections in
8677a7dea167SDimitry Andric           // `TransformTypoExpr`.
8678a7dea167SDimitry Andric           TransformCache.erase(TE);
8679a7dea167SDimitry Andric           ExprResult AmbigRes = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous);
8680a7dea167SDimitry Andric 
8681a7dea167SDimitry Andric           if (!AmbigRes.isInvalid() || IsAmbiguous) {
8682a7dea167SDimitry Andric             SemaRef.getTypoExprState(TE).Consumer->resetCorrectionStream();
8683a7dea167SDimitry Andric             SavedTransformCache.erase(TE);
8684a7dea167SDimitry Andric             Res = ExprError();
8685a7dea167SDimitry Andric             IsAmbiguous = true;
8686a7dea167SDimitry Andric             break;
8687a7dea167SDimitry Andric           }
8688a7dea167SDimitry Andric         } while ((Next = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection()) &&
8689a7dea167SDimitry Andric                  Next.getEditDistance(false) == TC.getEditDistance(false));
8690a7dea167SDimitry Andric 
8691a7dea167SDimitry Andric         if (IsAmbiguous)
8692a7dea167SDimitry Andric           break;
8693a7dea167SDimitry Andric 
8694a7dea167SDimitry Andric         AmbiguousTypoExprs.remove(TE);
8695a7dea167SDimitry Andric         SemaRef.getTypoExprState(TE).Consumer->restoreSavedPosition();
8696fe6060f1SDimitry Andric         TransformCache[TE] = SavedTransformCache[TE];
8697a7dea167SDimitry Andric       }
8698a7dea167SDimitry Andric       TransformCache = std::move(SavedTransformCache);
8699a7dea167SDimitry Andric     }
8700a7dea167SDimitry Andric 
8701a7dea167SDimitry Andric     // Wipe away any newly created TypoExprs that we don't know about. Since we
8702a7dea167SDimitry Andric     // clear any invalid TypoExprs in `CheckForRecursiveTypos`, this is only
8703a7dea167SDimitry Andric     // possible if a `TypoExpr` is created during a transformation but then
8704a7dea167SDimitry Andric     // fails before we can discover it.
8705a7dea167SDimitry Andric     auto &SemaTypoExprs = SemaRef.TypoExprs;
8706a7dea167SDimitry Andric     for (auto Iterator = SemaTypoExprs.begin(); Iterator != SemaTypoExprs.end();) {
8707a7dea167SDimitry Andric       auto TE = *Iterator;
8708a7dea167SDimitry Andric       auto FI = find(TypoExprs, TE);
8709a7dea167SDimitry Andric       if (FI != TypoExprs.end()) {
8710a7dea167SDimitry Andric         Iterator++;
8711a7dea167SDimitry Andric         continue;
8712a7dea167SDimitry Andric       }
8713a7dea167SDimitry Andric       SemaRef.clearDelayedTypo(TE);
8714a7dea167SDimitry Andric       Iterator = SemaTypoExprs.erase(Iterator);
8715a7dea167SDimitry Andric     }
8716a7dea167SDimitry Andric     SemaRef.TypoExprs = std::move(SavedTypoExprs);
8717a7dea167SDimitry Andric 
8718a7dea167SDimitry Andric     return Res;
8719a7dea167SDimitry Andric   }
8720a7dea167SDimitry Andric 
87210b57cec5SDimitry Andric public:
TransformTypos(Sema & SemaRef,VarDecl * InitDecl,llvm::function_ref<ExprResult (Expr *)> Filter)87220b57cec5SDimitry Andric   TransformTypos(Sema &SemaRef, VarDecl *InitDecl, llvm::function_ref<ExprResult(Expr *)> Filter)
87230b57cec5SDimitry Andric       : BaseTransform(SemaRef), InitDecl(InitDecl), ExprFilter(Filter) {}
87240b57cec5SDimitry Andric 
RebuildCallExpr(Expr * Callee,SourceLocation LParenLoc,MultiExprArg Args,SourceLocation RParenLoc,Expr * ExecConfig=nullptr)87250b57cec5SDimitry Andric   ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
87260b57cec5SDimitry Andric                                    MultiExprArg Args,
87270b57cec5SDimitry Andric                                    SourceLocation RParenLoc,
87280b57cec5SDimitry Andric                                    Expr *ExecConfig = nullptr) {
87290b57cec5SDimitry Andric     auto Result = BaseTransform::RebuildCallExpr(Callee, LParenLoc, Args,
87300b57cec5SDimitry Andric                                                  RParenLoc, ExecConfig);
87310b57cec5SDimitry Andric     if (auto *OE = dyn_cast<OverloadExpr>(Callee)) {
87320b57cec5SDimitry Andric       if (Result.isUsable()) {
87330b57cec5SDimitry Andric         Expr *ResultCall = Result.get();
87340b57cec5SDimitry Andric         if (auto *BE = dyn_cast<CXXBindTemporaryExpr>(ResultCall))
87350b57cec5SDimitry Andric           ResultCall = BE->getSubExpr();
87360b57cec5SDimitry Andric         if (auto *CE = dyn_cast<CallExpr>(ResultCall))
87370b57cec5SDimitry Andric           OverloadResolution[OE] = CE->getCallee();
87380b57cec5SDimitry Andric       }
87390b57cec5SDimitry Andric     }
87400b57cec5SDimitry Andric     return Result;
87410b57cec5SDimitry Andric   }
87420b57cec5SDimitry Andric 
TransformLambdaExpr(LambdaExpr * E)87430b57cec5SDimitry Andric   ExprResult TransformLambdaExpr(LambdaExpr *E) { return Owned(E); }
87440b57cec5SDimitry Andric 
TransformBlockExpr(BlockExpr * E)87450b57cec5SDimitry Andric   ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); }
87460b57cec5SDimitry Andric 
Transform(Expr * E)87470b57cec5SDimitry Andric   ExprResult Transform(Expr *E) {
8748a7dea167SDimitry Andric     bool IsAmbiguous = false;
8749a7dea167SDimitry Andric     ExprResult Res = RecursiveTransformLoop(E, IsAmbiguous);
87500b57cec5SDimitry Andric 
87510b57cec5SDimitry Andric     if (!Res.isUsable())
87520b57cec5SDimitry Andric       FindTypoExprs(TypoExprs).TraverseStmt(E);
87530b57cec5SDimitry Andric 
8754a7dea167SDimitry Andric     EmitAllDiagnostics(IsAmbiguous);
87550b57cec5SDimitry Andric 
87560b57cec5SDimitry Andric     return Res;
87570b57cec5SDimitry Andric   }
87580b57cec5SDimitry Andric 
TransformTypoExpr(TypoExpr * E)87590b57cec5SDimitry Andric   ExprResult TransformTypoExpr(TypoExpr *E) {
87600b57cec5SDimitry Andric     // If the TypoExpr hasn't been seen before, record it. Otherwise, return the
87610b57cec5SDimitry Andric     // cached transformation result if there is one and the TypoExpr isn't the
87620b57cec5SDimitry Andric     // first one that was encountered.
87630b57cec5SDimitry Andric     auto &CacheEntry = TransformCache[E];
87640b57cec5SDimitry Andric     if (!TypoExprs.insert(E) && !CacheEntry.isUnset()) {
87650b57cec5SDimitry Andric       return CacheEntry;
87660b57cec5SDimitry Andric     }
87670b57cec5SDimitry Andric 
87680b57cec5SDimitry Andric     auto &State = SemaRef.getTypoExprState(E);
87690b57cec5SDimitry Andric     assert(State.Consumer && "Cannot transform a cleared TypoExpr");
87700b57cec5SDimitry Andric 
87710b57cec5SDimitry Andric     // For the first TypoExpr and an uncached TypoExpr, find the next likely
87720b57cec5SDimitry Andric     // typo correction and return it.
87730b57cec5SDimitry Andric     while (TypoCorrection TC = State.Consumer->getNextCorrection()) {
87740b57cec5SDimitry Andric       if (InitDecl && TC.getFoundDecl() == InitDecl)
87750b57cec5SDimitry Andric         continue;
87760b57cec5SDimitry Andric       // FIXME: If we would typo-correct to an invalid declaration, it's
87770b57cec5SDimitry Andric       // probably best to just suppress all errors from this typo correction.
87780b57cec5SDimitry Andric       ExprResult NE = State.RecoveryHandler ?
87790b57cec5SDimitry Andric           State.RecoveryHandler(SemaRef, E, TC) :
87800b57cec5SDimitry Andric           attemptRecovery(SemaRef, *State.Consumer, TC);
87810b57cec5SDimitry Andric       if (!NE.isInvalid()) {
87820b57cec5SDimitry Andric         // Check whether there may be a second viable correction with the same
87830b57cec5SDimitry Andric         // edit distance; if so, remember this TypoExpr may have an ambiguous
87840b57cec5SDimitry Andric         // correction so it can be more thoroughly vetted later.
87850b57cec5SDimitry Andric         TypoCorrection Next;
87860b57cec5SDimitry Andric         if ((Next = State.Consumer->peekNextCorrection()) &&
87870b57cec5SDimitry Andric             Next.getEditDistance(false) == TC.getEditDistance(false)) {
87880b57cec5SDimitry Andric           AmbiguousTypoExprs.insert(E);
87890b57cec5SDimitry Andric         } else {
87900b57cec5SDimitry Andric           AmbiguousTypoExprs.remove(E);
87910b57cec5SDimitry Andric         }
87920b57cec5SDimitry Andric         assert(!NE.isUnset() &&
87930b57cec5SDimitry Andric                "Typo was transformed into a valid-but-null ExprResult");
87940b57cec5SDimitry Andric         return CacheEntry = NE;
87950b57cec5SDimitry Andric       }
87960b57cec5SDimitry Andric     }
87970b57cec5SDimitry Andric     return CacheEntry = ExprError();
87980b57cec5SDimitry Andric   }
87990b57cec5SDimitry Andric };
88000b57cec5SDimitry Andric }
88010b57cec5SDimitry Andric 
88020b57cec5SDimitry Andric ExprResult
CorrectDelayedTyposInExpr(Expr * E,VarDecl * InitDecl,bool RecoverUncorrectedTypos,llvm::function_ref<ExprResult (Expr *)> Filter)88030b57cec5SDimitry Andric Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl,
88045ffd83dbSDimitry Andric                                 bool RecoverUncorrectedTypos,
88050b57cec5SDimitry Andric                                 llvm::function_ref<ExprResult(Expr *)> Filter) {
88060b57cec5SDimitry Andric   // If the current evaluation context indicates there are uncorrected typos
88070b57cec5SDimitry Andric   // and the current expression isn't guaranteed to not have typos, try to
88080b57cec5SDimitry Andric   // resolve any TypoExpr nodes that might be in the expression.
88090b57cec5SDimitry Andric   if (E && !ExprEvalContexts.empty() && ExprEvalContexts.back().NumTypos &&
88100b57cec5SDimitry Andric       (E->isTypeDependent() || E->isValueDependent() ||
88110b57cec5SDimitry Andric        E->isInstantiationDependent())) {
88120b57cec5SDimitry Andric     auto TyposResolved = DelayedTypos.size();
88130b57cec5SDimitry Andric     auto Result = TransformTypos(*this, InitDecl, Filter).Transform(E);
88140b57cec5SDimitry Andric     TyposResolved -= DelayedTypos.size();
88150b57cec5SDimitry Andric     if (Result.isInvalid() || Result.get() != E) {
88160b57cec5SDimitry Andric       ExprEvalContexts.back().NumTypos -= TyposResolved;
88175ffd83dbSDimitry Andric       if (Result.isInvalid() && RecoverUncorrectedTypos) {
88185ffd83dbSDimitry Andric         struct TyposReplace : TreeTransform<TyposReplace> {
88195ffd83dbSDimitry Andric           TyposReplace(Sema &SemaRef) : TreeTransform(SemaRef) {}
88205ffd83dbSDimitry Andric           ExprResult TransformTypoExpr(clang::TypoExpr *E) {
88215ffd83dbSDimitry Andric             return this->SemaRef.CreateRecoveryExpr(E->getBeginLoc(),
88225ffd83dbSDimitry Andric                                                     E->getEndLoc(), {});
88235ffd83dbSDimitry Andric           }
88245ffd83dbSDimitry Andric         } TT(*this);
88255ffd83dbSDimitry Andric         return TT.TransformExpr(E);
88265ffd83dbSDimitry Andric       }
88270b57cec5SDimitry Andric       return Result;
88280b57cec5SDimitry Andric     }
88290b57cec5SDimitry Andric     assert(TyposResolved == 0 && "Corrected typo but got same Expr back?");
88300b57cec5SDimitry Andric   }
88310b57cec5SDimitry Andric   return E;
88320b57cec5SDimitry Andric }
88330b57cec5SDimitry Andric 
ActOnFinishFullExpr(Expr * FE,SourceLocation CC,bool DiscardedValue,bool IsConstexpr,bool IsTemplateArgument)88340b57cec5SDimitry Andric ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
8835bdd1243dSDimitry Andric                                      bool DiscardedValue, bool IsConstexpr,
8836bdd1243dSDimitry Andric                                      bool IsTemplateArgument) {
88370b57cec5SDimitry Andric   ExprResult FullExpr = FE;
88380b57cec5SDimitry Andric 
88390b57cec5SDimitry Andric   if (!FullExpr.get())
88400b57cec5SDimitry Andric     return ExprError();
88410b57cec5SDimitry Andric 
8842bdd1243dSDimitry Andric   if (!IsTemplateArgument && DiagnoseUnexpandedParameterPack(FullExpr.get()))
88430b57cec5SDimitry Andric     return ExprError();
88440b57cec5SDimitry Andric 
88450b57cec5SDimitry Andric   if (DiscardedValue) {
88460b57cec5SDimitry Andric     // Top-level expressions default to 'id' when we're in a debugger.
88470b57cec5SDimitry Andric     if (getLangOpts().DebuggerCastResultToId &&
88480b57cec5SDimitry Andric         FullExpr.get()->getType() == Context.UnknownAnyTy) {
88490b57cec5SDimitry Andric       FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType());
88500b57cec5SDimitry Andric       if (FullExpr.isInvalid())
88510b57cec5SDimitry Andric         return ExprError();
88520b57cec5SDimitry Andric     }
88530b57cec5SDimitry Andric 
88540b57cec5SDimitry Andric     FullExpr = CheckPlaceholderExpr(FullExpr.get());
88550b57cec5SDimitry Andric     if (FullExpr.isInvalid())
88560b57cec5SDimitry Andric       return ExprError();
88570b57cec5SDimitry Andric 
88580b57cec5SDimitry Andric     FullExpr = IgnoredValueConversions(FullExpr.get());
88590b57cec5SDimitry Andric     if (FullExpr.isInvalid())
88600b57cec5SDimitry Andric       return ExprError();
88610b57cec5SDimitry Andric 
8862349cc55cSDimitry Andric     DiagnoseUnusedExprResult(FullExpr.get(), diag::warn_unused_expr);
88630b57cec5SDimitry Andric   }
88640b57cec5SDimitry Andric 
88655ffd83dbSDimitry Andric   FullExpr = CorrectDelayedTyposInExpr(FullExpr.get(), /*InitDecl=*/nullptr,
88665ffd83dbSDimitry Andric                                        /*RecoverUncorrectedTypos=*/true);
88670b57cec5SDimitry Andric   if (FullExpr.isInvalid())
88680b57cec5SDimitry Andric     return ExprError();
88690b57cec5SDimitry Andric 
88700b57cec5SDimitry Andric   CheckCompletedExpr(FullExpr.get(), CC, IsConstexpr);
88710b57cec5SDimitry Andric 
88720b57cec5SDimitry Andric   // At the end of this full expression (which could be a deeply nested
88730b57cec5SDimitry Andric   // lambda), if there is a potential capture within the nested lambda,
88740b57cec5SDimitry Andric   // have the outer capture-able lambda try and capture it.
88750b57cec5SDimitry Andric   // Consider the following code:
88760b57cec5SDimitry Andric   // void f(int, int);
88770b57cec5SDimitry Andric   // void f(const int&, double);
88780b57cec5SDimitry Andric   // void foo() {
88790b57cec5SDimitry Andric   //  const int x = 10, y = 20;
88800b57cec5SDimitry Andric   //  auto L = [=](auto a) {
88810b57cec5SDimitry Andric   //      auto M = [=](auto b) {
88820b57cec5SDimitry Andric   //         f(x, b); <-- requires x to be captured by L and M
88830b57cec5SDimitry Andric   //         f(y, a); <-- requires y to be captured by L, but not all Ms
88840b57cec5SDimitry Andric   //      };
88850b57cec5SDimitry Andric   //   };
88860b57cec5SDimitry Andric   // }
88870b57cec5SDimitry Andric 
88880b57cec5SDimitry Andric   // FIXME: Also consider what happens for something like this that involves
88890b57cec5SDimitry Andric   // the gnu-extension statement-expressions or even lambda-init-captures:
88900b57cec5SDimitry Andric   //   void f() {
88910b57cec5SDimitry Andric   //     const int n = 0;
88920b57cec5SDimitry Andric   //     auto L =  [&](auto a) {
88930b57cec5SDimitry Andric   //       +n + ({ 0; a; });
88940b57cec5SDimitry Andric   //     };
88950b57cec5SDimitry Andric   //   }
88960b57cec5SDimitry Andric   //
88970b57cec5SDimitry Andric   // Here, we see +n, and then the full-expression 0; ends, so we don't
88980b57cec5SDimitry Andric   // capture n (and instead remove it from our list of potential captures),
88990b57cec5SDimitry Andric   // and then the full-expression +n + ({ 0; }); ends, but it's too late
89000b57cec5SDimitry Andric   // for us to see that we need to capture n after all.
89010b57cec5SDimitry Andric 
89020b57cec5SDimitry Andric   LambdaScopeInfo *const CurrentLSI =
89030b57cec5SDimitry Andric       getCurLambda(/*IgnoreCapturedRegions=*/true);
89040b57cec5SDimitry Andric   // FIXME: PR 17877 showed that getCurLambda() can return a valid pointer
89050b57cec5SDimitry Andric   // even if CurContext is not a lambda call operator. Refer to that Bug Report
89060b57cec5SDimitry Andric   // for an example of the code that might cause this asynchrony.
89070b57cec5SDimitry Andric   // By ensuring we are in the context of a lambda's call operator
89080b57cec5SDimitry Andric   // we can fix the bug (we only need to check whether we need to capture
89090b57cec5SDimitry Andric   // if we are within a lambda's body); but per the comments in that
89100b57cec5SDimitry Andric   // PR, a proper fix would entail :
89110b57cec5SDimitry Andric   //   "Alternative suggestion:
89120b57cec5SDimitry Andric   //   - Add to Sema an integer holding the smallest (outermost) scope
89130b57cec5SDimitry Andric   //     index that we are *lexically* within, and save/restore/set to
89140b57cec5SDimitry Andric   //     FunctionScopes.size() in InstantiatingTemplate's
89150b57cec5SDimitry Andric   //     constructor/destructor.
89160b57cec5SDimitry Andric   //  - Teach the handful of places that iterate over FunctionScopes to
89170b57cec5SDimitry Andric   //    stop at the outermost enclosing lexical scope."
89180b57cec5SDimitry Andric   DeclContext *DC = CurContext;
89190b57cec5SDimitry Andric   while (DC && isa<CapturedDecl>(DC))
89200b57cec5SDimitry Andric     DC = DC->getParent();
89210b57cec5SDimitry Andric   const bool IsInLambdaDeclContext = isLambdaCallOperator(DC);
89220b57cec5SDimitry Andric   if (IsInLambdaDeclContext && CurrentLSI &&
89230b57cec5SDimitry Andric       CurrentLSI->hasPotentialCaptures() && !FullExpr.isInvalid())
89240b57cec5SDimitry Andric     CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(FE, CurrentLSI,
89250b57cec5SDimitry Andric                                                               *this);
89260b57cec5SDimitry Andric   return MaybeCreateExprWithCleanups(FullExpr);
89270b57cec5SDimitry Andric }
89280b57cec5SDimitry Andric 
ActOnFinishFullStmt(Stmt * FullStmt)89290b57cec5SDimitry Andric StmtResult Sema::ActOnFinishFullStmt(Stmt *FullStmt) {
89300b57cec5SDimitry Andric   if (!FullStmt) return StmtError();
89310b57cec5SDimitry Andric 
89320b57cec5SDimitry Andric   return MaybeCreateStmtWithCleanups(FullStmt);
89330b57cec5SDimitry Andric }
89340b57cec5SDimitry Andric 
89350b57cec5SDimitry Andric Sema::IfExistsResult
CheckMicrosoftIfExistsSymbol(Scope * S,CXXScopeSpec & SS,const DeclarationNameInfo & TargetNameInfo)89360b57cec5SDimitry Andric Sema::CheckMicrosoftIfExistsSymbol(Scope *S,
89370b57cec5SDimitry Andric                                    CXXScopeSpec &SS,
89380b57cec5SDimitry Andric                                    const DeclarationNameInfo &TargetNameInfo) {
89390b57cec5SDimitry Andric   DeclarationName TargetName = TargetNameInfo.getName();
89400b57cec5SDimitry Andric   if (!TargetName)
89410b57cec5SDimitry Andric     return IER_DoesNotExist;
89420b57cec5SDimitry Andric 
89430b57cec5SDimitry Andric   // If the name itself is dependent, then the result is dependent.
89440b57cec5SDimitry Andric   if (TargetName.isDependentName())
89450b57cec5SDimitry Andric     return IER_Dependent;
89460b57cec5SDimitry Andric 
89470b57cec5SDimitry Andric   // Do the redeclaration lookup in the current scope.
89480b57cec5SDimitry Andric   LookupResult R(*this, TargetNameInfo, Sema::LookupAnyName,
89490b57cec5SDimitry Andric                  Sema::NotForRedeclaration);
89500b57cec5SDimitry Andric   LookupParsedName(R, S, &SS);
89510b57cec5SDimitry Andric   R.suppressDiagnostics();
89520b57cec5SDimitry Andric 
89530b57cec5SDimitry Andric   switch (R.getResultKind()) {
89540b57cec5SDimitry Andric   case LookupResult::Found:
89550b57cec5SDimitry Andric   case LookupResult::FoundOverloaded:
89560b57cec5SDimitry Andric   case LookupResult::FoundUnresolvedValue:
89570b57cec5SDimitry Andric   case LookupResult::Ambiguous:
89580b57cec5SDimitry Andric     return IER_Exists;
89590b57cec5SDimitry Andric 
89600b57cec5SDimitry Andric   case LookupResult::NotFound:
89610b57cec5SDimitry Andric     return IER_DoesNotExist;
89620b57cec5SDimitry Andric 
89630b57cec5SDimitry Andric   case LookupResult::NotFoundInCurrentInstantiation:
89640b57cec5SDimitry Andric     return IER_Dependent;
89650b57cec5SDimitry Andric   }
89660b57cec5SDimitry Andric 
89670b57cec5SDimitry Andric   llvm_unreachable("Invalid LookupResult Kind!");
89680b57cec5SDimitry Andric }
89690b57cec5SDimitry Andric 
89700b57cec5SDimitry Andric Sema::IfExistsResult
CheckMicrosoftIfExistsSymbol(Scope * S,SourceLocation KeywordLoc,bool IsIfExists,CXXScopeSpec & SS,UnqualifiedId & Name)89710b57cec5SDimitry Andric Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
89720b57cec5SDimitry Andric                                    bool IsIfExists, CXXScopeSpec &SS,
89730b57cec5SDimitry Andric                                    UnqualifiedId &Name) {
89740b57cec5SDimitry Andric   DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
89750b57cec5SDimitry Andric 
89760b57cec5SDimitry Andric   // Check for an unexpanded parameter pack.
89770b57cec5SDimitry Andric   auto UPPC = IsIfExists ? UPPC_IfExists : UPPC_IfNotExists;
89780b57cec5SDimitry Andric   if (DiagnoseUnexpandedParameterPack(SS, UPPC) ||
89790b57cec5SDimitry Andric       DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC))
89800b57cec5SDimitry Andric     return IER_Error;
89810b57cec5SDimitry Andric 
89820b57cec5SDimitry Andric   return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo);
89830b57cec5SDimitry Andric }
898455e4f9d5SDimitry Andric 
ActOnSimpleRequirement(Expr * E)898555e4f9d5SDimitry Andric concepts::Requirement *Sema::ActOnSimpleRequirement(Expr *E) {
898655e4f9d5SDimitry Andric   return BuildExprRequirement(E, /*IsSimple=*/true,
898755e4f9d5SDimitry Andric                               /*NoexceptLoc=*/SourceLocation(),
898855e4f9d5SDimitry Andric                               /*ReturnTypeRequirement=*/{});
898955e4f9d5SDimitry Andric }
899055e4f9d5SDimitry Andric 
899155e4f9d5SDimitry Andric concepts::Requirement *
ActOnTypeRequirement(SourceLocation TypenameKWLoc,CXXScopeSpec & SS,SourceLocation NameLoc,IdentifierInfo * TypeName,TemplateIdAnnotation * TemplateId)899255e4f9d5SDimitry Andric Sema::ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS,
899355e4f9d5SDimitry Andric                            SourceLocation NameLoc, IdentifierInfo *TypeName,
899455e4f9d5SDimitry Andric                            TemplateIdAnnotation *TemplateId) {
899555e4f9d5SDimitry Andric   assert(((!TypeName && TemplateId) || (TypeName && !TemplateId)) &&
899655e4f9d5SDimitry Andric          "Exactly one of TypeName and TemplateId must be specified.");
899755e4f9d5SDimitry Andric   TypeSourceInfo *TSI = nullptr;
899855e4f9d5SDimitry Andric   if (TypeName) {
89995f757f3fSDimitry Andric     QualType T =
90005f757f3fSDimitry Andric         CheckTypenameType(ElaboratedTypeKeyword::Typename, TypenameKWLoc,
90015f757f3fSDimitry Andric                           SS.getWithLocInContext(Context), *TypeName, NameLoc,
90025f757f3fSDimitry Andric                           &TSI, /*DeducedTSTContext=*/false);
900355e4f9d5SDimitry Andric     if (T.isNull())
900455e4f9d5SDimitry Andric       return nullptr;
900555e4f9d5SDimitry Andric   } else {
900655e4f9d5SDimitry Andric     ASTTemplateArgsPtr ArgsPtr(TemplateId->getTemplateArgs(),
900755e4f9d5SDimitry Andric                                TemplateId->NumArgs);
900855e4f9d5SDimitry Andric     TypeResult T = ActOnTypenameType(CurScope, TypenameKWLoc, SS,
900955e4f9d5SDimitry Andric                                      TemplateId->TemplateKWLoc,
901055e4f9d5SDimitry Andric                                      TemplateId->Template, TemplateId->Name,
901155e4f9d5SDimitry Andric                                      TemplateId->TemplateNameLoc,
901255e4f9d5SDimitry Andric                                      TemplateId->LAngleLoc, ArgsPtr,
901355e4f9d5SDimitry Andric                                      TemplateId->RAngleLoc);
901455e4f9d5SDimitry Andric     if (T.isInvalid())
901555e4f9d5SDimitry Andric       return nullptr;
901655e4f9d5SDimitry Andric     if (GetTypeFromParser(T.get(), &TSI).isNull())
901755e4f9d5SDimitry Andric       return nullptr;
901855e4f9d5SDimitry Andric   }
901955e4f9d5SDimitry Andric   return BuildTypeRequirement(TSI);
902055e4f9d5SDimitry Andric }
902155e4f9d5SDimitry Andric 
902255e4f9d5SDimitry Andric concepts::Requirement *
ActOnCompoundRequirement(Expr * E,SourceLocation NoexceptLoc)902355e4f9d5SDimitry Andric Sema::ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc) {
902455e4f9d5SDimitry Andric   return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc,
902555e4f9d5SDimitry Andric                               /*ReturnTypeRequirement=*/{});
902655e4f9d5SDimitry Andric }
902755e4f9d5SDimitry Andric 
902855e4f9d5SDimitry Andric concepts::Requirement *
ActOnCompoundRequirement(Expr * E,SourceLocation NoexceptLoc,CXXScopeSpec & SS,TemplateIdAnnotation * TypeConstraint,unsigned Depth)902955e4f9d5SDimitry Andric Sema::ActOnCompoundRequirement(
903055e4f9d5SDimitry Andric     Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS,
903155e4f9d5SDimitry Andric     TemplateIdAnnotation *TypeConstraint, unsigned Depth) {
903255e4f9d5SDimitry Andric   // C++2a [expr.prim.req.compound] p1.3.3
903355e4f9d5SDimitry Andric   //   [..] the expression is deduced against an invented function template
903455e4f9d5SDimitry Andric   //   F [...] F is a void function template with a single type template
903555e4f9d5SDimitry Andric   //   parameter T declared with the constrained-parameter. Form a new
903655e4f9d5SDimitry Andric   //   cv-qualifier-seq cv by taking the union of const and volatile specifiers
903755e4f9d5SDimitry Andric   //   around the constrained-parameter. F has a single parameter whose
903855e4f9d5SDimitry Andric   //   type-specifier is cv T followed by the abstract-declarator. [...]
903955e4f9d5SDimitry Andric   //
904055e4f9d5SDimitry Andric   // The cv part is done in the calling function - we get the concept with
904155e4f9d5SDimitry Andric   // arguments and the abstract declarator with the correct CV qualification and
904255e4f9d5SDimitry Andric   // have to synthesize T and the single parameter of F.
904355e4f9d5SDimitry Andric   auto &II = Context.Idents.get("expr-type");
904455e4f9d5SDimitry Andric   auto *TParam = TemplateTypeParmDecl::Create(Context, CurContext,
904555e4f9d5SDimitry Andric                                               SourceLocation(),
904655e4f9d5SDimitry Andric                                               SourceLocation(), Depth,
904755e4f9d5SDimitry Andric                                               /*Index=*/0, &II,
904855e4f9d5SDimitry Andric                                               /*Typename=*/true,
904955e4f9d5SDimitry Andric                                               /*ParameterPack=*/false,
905055e4f9d5SDimitry Andric                                               /*HasTypeConstraint=*/true);
905155e4f9d5SDimitry Andric 
9052fe6060f1SDimitry Andric   if (BuildTypeConstraint(SS, TypeConstraint, TParam,
905304eeddc0SDimitry Andric                           /*EllipsisLoc=*/SourceLocation(),
9054fe6060f1SDimitry Andric                           /*AllowUnexpandedPack=*/true))
905555e4f9d5SDimitry Andric     // Just produce a requirement with no type requirements.
905655e4f9d5SDimitry Andric     return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc, {});
905755e4f9d5SDimitry Andric 
905855e4f9d5SDimitry Andric   auto *TPL = TemplateParameterList::Create(Context, SourceLocation(),
905955e4f9d5SDimitry Andric                                             SourceLocation(),
906055e4f9d5SDimitry Andric                                             ArrayRef<NamedDecl *>(TParam),
906155e4f9d5SDimitry Andric                                             SourceLocation(),
906255e4f9d5SDimitry Andric                                             /*RequiresClause=*/nullptr);
906355e4f9d5SDimitry Andric   return BuildExprRequirement(
906455e4f9d5SDimitry Andric       E, /*IsSimple=*/false, NoexceptLoc,
906555e4f9d5SDimitry Andric       concepts::ExprRequirement::ReturnTypeRequirement(TPL));
906655e4f9d5SDimitry Andric }
906755e4f9d5SDimitry Andric 
906855e4f9d5SDimitry Andric concepts::ExprRequirement *
BuildExprRequirement(Expr * E,bool IsSimple,SourceLocation NoexceptLoc,concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement)906955e4f9d5SDimitry Andric Sema::BuildExprRequirement(
907055e4f9d5SDimitry Andric     Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
907155e4f9d5SDimitry Andric     concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {
907255e4f9d5SDimitry Andric   auto Status = concepts::ExprRequirement::SS_Satisfied;
907355e4f9d5SDimitry Andric   ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
90745f757f3fSDimitry Andric   if (E->isInstantiationDependent() || E->getType()->isPlaceholderType() ||
90755f757f3fSDimitry Andric       ReturnTypeRequirement.isDependent())
907655e4f9d5SDimitry Andric     Status = concepts::ExprRequirement::SS_Dependent;
907755e4f9d5SDimitry Andric   else if (NoexceptLoc.isValid() && canThrow(E) == CanThrowResult::CT_Can)
907855e4f9d5SDimitry Andric     Status = concepts::ExprRequirement::SS_NoexceptNotMet;
907955e4f9d5SDimitry Andric   else if (ReturnTypeRequirement.isSubstitutionFailure())
908055e4f9d5SDimitry Andric     Status = concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure;
908155e4f9d5SDimitry Andric   else if (ReturnTypeRequirement.isTypeConstraint()) {
908255e4f9d5SDimitry Andric     // C++2a [expr.prim.req]p1.3.3
908355e4f9d5SDimitry Andric     //     The immediately-declared constraint ([temp]) of decltype((E)) shall
908455e4f9d5SDimitry Andric     //     be satisfied.
908555e4f9d5SDimitry Andric     TemplateParameterList *TPL =
908655e4f9d5SDimitry Andric         ReturnTypeRequirement.getTypeConstraintTemplateParameterList();
908755e4f9d5SDimitry Andric     QualType MatchedType =
9088349cc55cSDimitry Andric         Context.getReferenceQualifiedType(E).getCanonicalType();
908955e4f9d5SDimitry Andric     llvm::SmallVector<TemplateArgument, 1> Args;
909055e4f9d5SDimitry Andric     Args.push_back(TemplateArgument(MatchedType));
9091bdd1243dSDimitry Andric 
9092bdd1243dSDimitry Andric     auto *Param = cast<TemplateTypeParmDecl>(TPL->getParam(0));
9093bdd1243dSDimitry Andric 
909455e4f9d5SDimitry Andric     TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args);
9095bdd1243dSDimitry Andric     MultiLevelTemplateArgumentList MLTAL(Param, TAL.asArray(),
9096bdd1243dSDimitry Andric                                          /*Final=*/false);
9097bdd1243dSDimitry Andric     MLTAL.addOuterRetainedLevels(TPL->getDepth());
90988a4dda33SDimitry Andric     const TypeConstraint *TC = Param->getTypeConstraint();
90998a4dda33SDimitry Andric     assert(TC && "Type Constraint cannot be null here");
91008a4dda33SDimitry Andric     auto *IDC = TC->getImmediatelyDeclaredConstraint();
91018a4dda33SDimitry Andric     assert(IDC && "ImmediatelyDeclaredConstraint can't be null here.");
910255e4f9d5SDimitry Andric     ExprResult Constraint = SubstExpr(IDC, MLTAL);
9103fcaf7f86SDimitry Andric     if (Constraint.isInvalid()) {
91048a4dda33SDimitry Andric       return new (Context) concepts::ExprRequirement(
91058a4dda33SDimitry Andric           concepts::createSubstDiagAt(*this, IDC->getExprLoc(),
91068a4dda33SDimitry Andric                                       [&](llvm::raw_ostream &OS) {
91078a4dda33SDimitry Andric                                         IDC->printPretty(OS, /*Helper=*/nullptr,
91088a4dda33SDimitry Andric                                                          getPrintingPolicy());
91098a4dda33SDimitry Andric                                       }),
91108a4dda33SDimitry Andric           IsSimple, NoexceptLoc, ReturnTypeRequirement);
91118a4dda33SDimitry Andric     }
911255e4f9d5SDimitry Andric     SubstitutedConstraintExpr =
911355e4f9d5SDimitry Andric         cast<ConceptSpecializationExpr>(Constraint.get());
911455e4f9d5SDimitry Andric     if (!SubstitutedConstraintExpr->isSatisfied())
911555e4f9d5SDimitry Andric       Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied;
911655e4f9d5SDimitry Andric   }
911755e4f9d5SDimitry Andric   return new (Context) concepts::ExprRequirement(E, IsSimple, NoexceptLoc,
911855e4f9d5SDimitry Andric                                                  ReturnTypeRequirement, Status,
911955e4f9d5SDimitry Andric                                                  SubstitutedConstraintExpr);
912055e4f9d5SDimitry Andric }
912155e4f9d5SDimitry Andric 
912255e4f9d5SDimitry Andric concepts::ExprRequirement *
BuildExprRequirement(concepts::Requirement::SubstitutionDiagnostic * ExprSubstitutionDiagnostic,bool IsSimple,SourceLocation NoexceptLoc,concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement)912355e4f9d5SDimitry Andric Sema::BuildExprRequirement(
912455e4f9d5SDimitry Andric     concepts::Requirement::SubstitutionDiagnostic *ExprSubstitutionDiagnostic,
912555e4f9d5SDimitry Andric     bool IsSimple, SourceLocation NoexceptLoc,
912655e4f9d5SDimitry Andric     concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {
912755e4f9d5SDimitry Andric   return new (Context) concepts::ExprRequirement(ExprSubstitutionDiagnostic,
912855e4f9d5SDimitry Andric                                                  IsSimple, NoexceptLoc,
912955e4f9d5SDimitry Andric                                                  ReturnTypeRequirement);
913055e4f9d5SDimitry Andric }
913155e4f9d5SDimitry Andric 
913255e4f9d5SDimitry Andric concepts::TypeRequirement *
BuildTypeRequirement(TypeSourceInfo * Type)913355e4f9d5SDimitry Andric Sema::BuildTypeRequirement(TypeSourceInfo *Type) {
913455e4f9d5SDimitry Andric   return new (Context) concepts::TypeRequirement(Type);
913555e4f9d5SDimitry Andric }
913655e4f9d5SDimitry Andric 
913755e4f9d5SDimitry Andric concepts::TypeRequirement *
BuildTypeRequirement(concepts::Requirement::SubstitutionDiagnostic * SubstDiag)913855e4f9d5SDimitry Andric Sema::BuildTypeRequirement(
913955e4f9d5SDimitry Andric     concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
914055e4f9d5SDimitry Andric   return new (Context) concepts::TypeRequirement(SubstDiag);
914155e4f9d5SDimitry Andric }
914255e4f9d5SDimitry Andric 
ActOnNestedRequirement(Expr * Constraint)914355e4f9d5SDimitry Andric concepts::Requirement *Sema::ActOnNestedRequirement(Expr *Constraint) {
914455e4f9d5SDimitry Andric   return BuildNestedRequirement(Constraint);
914555e4f9d5SDimitry Andric }
914655e4f9d5SDimitry Andric 
914755e4f9d5SDimitry Andric concepts::NestedRequirement *
BuildNestedRequirement(Expr * Constraint)914855e4f9d5SDimitry Andric Sema::BuildNestedRequirement(Expr *Constraint) {
914955e4f9d5SDimitry Andric   ConstraintSatisfaction Satisfaction;
915055e4f9d5SDimitry Andric   if (!Constraint->isInstantiationDependent() &&
915113138422SDimitry Andric       CheckConstraintSatisfaction(nullptr, {Constraint}, /*TemplateArgs=*/{},
915213138422SDimitry Andric                                   Constraint->getSourceRange(), Satisfaction))
915355e4f9d5SDimitry Andric     return nullptr;
915455e4f9d5SDimitry Andric   return new (Context) concepts::NestedRequirement(Context, Constraint,
915555e4f9d5SDimitry Andric                                                    Satisfaction);
915655e4f9d5SDimitry Andric }
915755e4f9d5SDimitry Andric 
915855e4f9d5SDimitry Andric concepts::NestedRequirement *
BuildNestedRequirement(StringRef InvalidConstraintEntity,const ASTConstraintSatisfaction & Satisfaction)9159bdd1243dSDimitry Andric Sema::BuildNestedRequirement(StringRef InvalidConstraintEntity,
9160bdd1243dSDimitry Andric                        const ASTConstraintSatisfaction &Satisfaction) {
9161bdd1243dSDimitry Andric   return new (Context) concepts::NestedRequirement(
9162bdd1243dSDimitry Andric       InvalidConstraintEntity,
9163bdd1243dSDimitry Andric       ASTConstraintSatisfaction::Rebuild(Context, Satisfaction));
916455e4f9d5SDimitry Andric }
916555e4f9d5SDimitry Andric 
916655e4f9d5SDimitry Andric RequiresExprBodyDecl *
ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,ArrayRef<ParmVarDecl * > LocalParameters,Scope * BodyScope)916755e4f9d5SDimitry Andric Sema::ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,
916855e4f9d5SDimitry Andric                              ArrayRef<ParmVarDecl *> LocalParameters,
916955e4f9d5SDimitry Andric                              Scope *BodyScope) {
917055e4f9d5SDimitry Andric   assert(BodyScope);
917155e4f9d5SDimitry Andric 
917255e4f9d5SDimitry Andric   RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(Context, CurContext,
917355e4f9d5SDimitry Andric                                                             RequiresKWLoc);
917455e4f9d5SDimitry Andric 
917555e4f9d5SDimitry Andric   PushDeclContext(BodyScope, Body);
917655e4f9d5SDimitry Andric 
917755e4f9d5SDimitry Andric   for (ParmVarDecl *Param : LocalParameters) {
917855e4f9d5SDimitry Andric     if (Param->hasDefaultArg())
917955e4f9d5SDimitry Andric       // C++2a [expr.prim.req] p4
918055e4f9d5SDimitry Andric       //     [...] A local parameter of a requires-expression shall not have a
918155e4f9d5SDimitry Andric       //     default argument. [...]
918255e4f9d5SDimitry Andric       Diag(Param->getDefaultArgRange().getBegin(),
918355e4f9d5SDimitry Andric            diag::err_requires_expr_local_parameter_default_argument);
918455e4f9d5SDimitry Andric     // Ignore default argument and move on
918555e4f9d5SDimitry Andric 
918655e4f9d5SDimitry Andric     Param->setDeclContext(Body);
918755e4f9d5SDimitry Andric     // If this has an identifier, add it to the scope stack.
918855e4f9d5SDimitry Andric     if (Param->getIdentifier()) {
918955e4f9d5SDimitry Andric       CheckShadow(BodyScope, Param);
919055e4f9d5SDimitry Andric       PushOnScopeChains(Param, BodyScope);
919155e4f9d5SDimitry Andric     }
919255e4f9d5SDimitry Andric   }
919355e4f9d5SDimitry Andric   return Body;
919455e4f9d5SDimitry Andric }
919555e4f9d5SDimitry Andric 
ActOnFinishRequiresExpr()919655e4f9d5SDimitry Andric void Sema::ActOnFinishRequiresExpr() {
919755e4f9d5SDimitry Andric   assert(CurContext && "DeclContext imbalance!");
919855e4f9d5SDimitry Andric   CurContext = CurContext->getLexicalParent();
919955e4f9d5SDimitry Andric   assert(CurContext && "Popped translation unit!");
920055e4f9d5SDimitry Andric }
920155e4f9d5SDimitry Andric 
ActOnRequiresExpr(SourceLocation RequiresKWLoc,RequiresExprBodyDecl * Body,SourceLocation LParenLoc,ArrayRef<ParmVarDecl * > LocalParameters,SourceLocation RParenLoc,ArrayRef<concepts::Requirement * > Requirements,SourceLocation ClosingBraceLoc)92025f757f3fSDimitry Andric ExprResult Sema::ActOnRequiresExpr(
92035f757f3fSDimitry Andric     SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body,
92045f757f3fSDimitry Andric     SourceLocation LParenLoc, ArrayRef<ParmVarDecl *> LocalParameters,
92055f757f3fSDimitry Andric     SourceLocation RParenLoc, ArrayRef<concepts::Requirement *> Requirements,
920655e4f9d5SDimitry Andric     SourceLocation ClosingBraceLoc) {
92075f757f3fSDimitry Andric   auto *RE = RequiresExpr::Create(Context, RequiresKWLoc, Body, LParenLoc,
92085f757f3fSDimitry Andric                                   LocalParameters, RParenLoc, Requirements,
92095f757f3fSDimitry Andric                                   ClosingBraceLoc);
9210e8d8bef9SDimitry Andric   if (DiagnoseUnexpandedParameterPackInRequiresExpr(RE))
9211e8d8bef9SDimitry Andric     return ExprError();
9212e8d8bef9SDimitry Andric   return RE;
921355e4f9d5SDimitry Andric }
9214