1e5dd7070Spatrick //===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick ///
9e5dd7070Spatrick /// \file
10e5dd7070Spatrick /// Implements semantic analysis for C++ expressions.
11e5dd7070Spatrick ///
12e5dd7070Spatrick //===----------------------------------------------------------------------===//
13e5dd7070Spatrick
14e5dd7070Spatrick #include "TreeTransform.h"
15e5dd7070Spatrick #include "TypeLocBuilder.h"
16e5dd7070Spatrick #include "clang/AST/ASTContext.h"
17e5dd7070Spatrick #include "clang/AST/ASTLambda.h"
18e5dd7070Spatrick #include "clang/AST/CXXInheritance.h"
19e5dd7070Spatrick #include "clang/AST/CharUnits.h"
20e5dd7070Spatrick #include "clang/AST/DeclObjC.h"
21e5dd7070Spatrick #include "clang/AST/ExprCXX.h"
22e5dd7070Spatrick #include "clang/AST/ExprObjC.h"
23e5dd7070Spatrick #include "clang/AST/RecursiveASTVisitor.h"
24*12c85518Srobert #include "clang/AST/Type.h"
25e5dd7070Spatrick #include "clang/AST/TypeLoc.h"
26e5dd7070Spatrick #include "clang/Basic/AlignedAllocation.h"
27*12c85518Srobert #include "clang/Basic/DiagnosticSema.h"
28e5dd7070Spatrick #include "clang/Basic/PartialDiagnostic.h"
29e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
30*12c85518Srobert #include "clang/Basic/TokenKinds.h"
31*12c85518Srobert #include "clang/Basic/TypeTraits.h"
32e5dd7070Spatrick #include "clang/Lex/Preprocessor.h"
33e5dd7070Spatrick #include "clang/Sema/DeclSpec.h"
34e5dd7070Spatrick #include "clang/Sema/Initialization.h"
35e5dd7070Spatrick #include "clang/Sema/Lookup.h"
36e5dd7070Spatrick #include "clang/Sema/ParsedTemplate.h"
37e5dd7070Spatrick #include "clang/Sema/Scope.h"
38e5dd7070Spatrick #include "clang/Sema/ScopeInfo.h"
39*12c85518Srobert #include "clang/Sema/SemaInternal.h"
40e5dd7070Spatrick #include "clang/Sema/SemaLambda.h"
41*12c85518Srobert #include "clang/Sema/Template.h"
42e5dd7070Spatrick #include "clang/Sema/TemplateDeduction.h"
43e5dd7070Spatrick #include "llvm/ADT/APInt.h"
44e5dd7070Spatrick #include "llvm/ADT/STLExtras.h"
45e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
46*12c85518Srobert #include "llvm/Support/TypeSize.h"
47*12c85518Srobert #include <optional>
48e5dd7070Spatrick using namespace clang;
49e5dd7070Spatrick using namespace sema;
50e5dd7070Spatrick
51e5dd7070Spatrick /// Handle the result of the special case name lookup for inheriting
52e5dd7070Spatrick /// constructor declarations. 'NS::X::X' and 'NS::X<...>::X' are treated as
53e5dd7070Spatrick /// constructor names in member using declarations, even if 'X' is not the
54e5dd7070Spatrick /// name of the corresponding type.
getInheritingConstructorName(CXXScopeSpec & SS,SourceLocation NameLoc,IdentifierInfo & Name)55e5dd7070Spatrick ParsedType Sema::getInheritingConstructorName(CXXScopeSpec &SS,
56e5dd7070Spatrick SourceLocation NameLoc,
57e5dd7070Spatrick IdentifierInfo &Name) {
58e5dd7070Spatrick NestedNameSpecifier *NNS = SS.getScopeRep();
59e5dd7070Spatrick
60e5dd7070Spatrick // Convert the nested-name-specifier into a type.
61e5dd7070Spatrick QualType Type;
62e5dd7070Spatrick switch (NNS->getKind()) {
63e5dd7070Spatrick case NestedNameSpecifier::TypeSpec:
64e5dd7070Spatrick case NestedNameSpecifier::TypeSpecWithTemplate:
65e5dd7070Spatrick Type = QualType(NNS->getAsType(), 0);
66e5dd7070Spatrick break;
67e5dd7070Spatrick
68e5dd7070Spatrick case NestedNameSpecifier::Identifier:
69e5dd7070Spatrick // Strip off the last layer of the nested-name-specifier and build a
70e5dd7070Spatrick // typename type for it.
71e5dd7070Spatrick assert(NNS->getAsIdentifier() == &Name && "not a constructor name");
72e5dd7070Spatrick Type = Context.getDependentNameType(ETK_None, NNS->getPrefix(),
73e5dd7070Spatrick NNS->getAsIdentifier());
74e5dd7070Spatrick break;
75e5dd7070Spatrick
76e5dd7070Spatrick case NestedNameSpecifier::Global:
77e5dd7070Spatrick case NestedNameSpecifier::Super:
78e5dd7070Spatrick case NestedNameSpecifier::Namespace:
79e5dd7070Spatrick case NestedNameSpecifier::NamespaceAlias:
80e5dd7070Spatrick llvm_unreachable("Nested name specifier is not a type for inheriting ctor");
81e5dd7070Spatrick }
82e5dd7070Spatrick
83e5dd7070Spatrick // This reference to the type is located entirely at the location of the
84e5dd7070Spatrick // final identifier in the qualified-id.
85e5dd7070Spatrick return CreateParsedType(Type,
86e5dd7070Spatrick Context.getTrivialTypeSourceInfo(Type, NameLoc));
87e5dd7070Spatrick }
88e5dd7070Spatrick
getConstructorName(IdentifierInfo & II,SourceLocation NameLoc,Scope * S,CXXScopeSpec & SS,bool EnteringContext)89e5dd7070Spatrick ParsedType Sema::getConstructorName(IdentifierInfo &II,
90e5dd7070Spatrick SourceLocation NameLoc,
91e5dd7070Spatrick Scope *S, CXXScopeSpec &SS,
92e5dd7070Spatrick bool EnteringContext) {
93e5dd7070Spatrick CXXRecordDecl *CurClass = getCurrentClass(S, &SS);
94e5dd7070Spatrick assert(CurClass && &II == CurClass->getIdentifier() &&
95e5dd7070Spatrick "not a constructor name");
96e5dd7070Spatrick
97e5dd7070Spatrick // When naming a constructor as a member of a dependent context (eg, in a
98e5dd7070Spatrick // friend declaration or an inherited constructor declaration), form an
99e5dd7070Spatrick // unresolved "typename" type.
100e5dd7070Spatrick if (CurClass->isDependentContext() && !EnteringContext && SS.getScopeRep()) {
101e5dd7070Spatrick QualType T = Context.getDependentNameType(ETK_None, SS.getScopeRep(), &II);
102e5dd7070Spatrick return ParsedType::make(T);
103e5dd7070Spatrick }
104e5dd7070Spatrick
105e5dd7070Spatrick if (SS.isNotEmpty() && RequireCompleteDeclContext(SS, CurClass))
106e5dd7070Spatrick return ParsedType();
107e5dd7070Spatrick
108e5dd7070Spatrick // Find the injected-class-name declaration. Note that we make no attempt to
109e5dd7070Spatrick // diagnose cases where the injected-class-name is shadowed: the only
110e5dd7070Spatrick // declaration that can validly shadow the injected-class-name is a
111e5dd7070Spatrick // non-static data member, and if the class contains both a non-static data
112e5dd7070Spatrick // member and a constructor then it is ill-formed (we check that in
113e5dd7070Spatrick // CheckCompletedCXXClass).
114e5dd7070Spatrick CXXRecordDecl *InjectedClassName = nullptr;
115e5dd7070Spatrick for (NamedDecl *ND : CurClass->lookup(&II)) {
116e5dd7070Spatrick auto *RD = dyn_cast<CXXRecordDecl>(ND);
117e5dd7070Spatrick if (RD && RD->isInjectedClassName()) {
118e5dd7070Spatrick InjectedClassName = RD;
119e5dd7070Spatrick break;
120e5dd7070Spatrick }
121e5dd7070Spatrick }
122e5dd7070Spatrick if (!InjectedClassName) {
123e5dd7070Spatrick if (!CurClass->isInvalidDecl()) {
124e5dd7070Spatrick // FIXME: RequireCompleteDeclContext doesn't check dependent contexts
125e5dd7070Spatrick // properly. Work around it here for now.
126e5dd7070Spatrick Diag(SS.getLastQualifierNameLoc(),
127e5dd7070Spatrick diag::err_incomplete_nested_name_spec) << CurClass << SS.getRange();
128e5dd7070Spatrick }
129e5dd7070Spatrick return ParsedType();
130e5dd7070Spatrick }
131e5dd7070Spatrick
132e5dd7070Spatrick QualType T = Context.getTypeDeclType(InjectedClassName);
133e5dd7070Spatrick DiagnoseUseOfDecl(InjectedClassName, NameLoc);
134e5dd7070Spatrick MarkAnyDeclReferenced(NameLoc, InjectedClassName, /*OdrUse=*/false);
135e5dd7070Spatrick
136e5dd7070Spatrick return ParsedType::make(T);
137e5dd7070Spatrick }
138e5dd7070Spatrick
getDestructorName(SourceLocation TildeLoc,IdentifierInfo & II,SourceLocation NameLoc,Scope * S,CXXScopeSpec & SS,ParsedType ObjectTypePtr,bool EnteringContext)139e5dd7070Spatrick ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
140e5dd7070Spatrick IdentifierInfo &II,
141e5dd7070Spatrick SourceLocation NameLoc,
142e5dd7070Spatrick Scope *S, CXXScopeSpec &SS,
143e5dd7070Spatrick ParsedType ObjectTypePtr,
144e5dd7070Spatrick bool EnteringContext) {
145e5dd7070Spatrick // Determine where to perform name lookup.
146e5dd7070Spatrick
147e5dd7070Spatrick // FIXME: This area of the standard is very messy, and the current
148e5dd7070Spatrick // wording is rather unclear about which scopes we search for the
149e5dd7070Spatrick // destructor name; see core issues 399 and 555. Issue 399 in
150e5dd7070Spatrick // particular shows where the current description of destructor name
151e5dd7070Spatrick // lookup is completely out of line with existing practice, e.g.,
152e5dd7070Spatrick // this appears to be ill-formed:
153e5dd7070Spatrick //
154e5dd7070Spatrick // namespace N {
155e5dd7070Spatrick // template <typename T> struct S {
156e5dd7070Spatrick // ~S();
157e5dd7070Spatrick // };
158e5dd7070Spatrick // }
159e5dd7070Spatrick //
160e5dd7070Spatrick // void f(N::S<int>* s) {
161e5dd7070Spatrick // s->N::S<int>::~S();
162e5dd7070Spatrick // }
163e5dd7070Spatrick //
164e5dd7070Spatrick // See also PR6358 and PR6359.
165ec727ea7Spatrick //
166ec727ea7Spatrick // For now, we accept all the cases in which the name given could plausibly
167ec727ea7Spatrick // be interpreted as a correct destructor name, issuing off-by-default
168ec727ea7Spatrick // extension diagnostics on the cases that don't strictly conform to the
169ec727ea7Spatrick // C++20 rules. This basically means we always consider looking in the
170ec727ea7Spatrick // nested-name-specifier prefix, the complete nested-name-specifier, and
171ec727ea7Spatrick // the scope, and accept if we find the expected type in any of the three
172ec727ea7Spatrick // places.
173e5dd7070Spatrick
174e5dd7070Spatrick if (SS.isInvalid())
175e5dd7070Spatrick return nullptr;
176e5dd7070Spatrick
177ec727ea7Spatrick // Whether we've failed with a diagnostic already.
178ec727ea7Spatrick bool Failed = false;
179ec727ea7Spatrick
180ec727ea7Spatrick llvm::SmallVector<NamedDecl*, 8> FoundDecls;
181a9ac8606Spatrick llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 8> FoundDeclSet;
182ec727ea7Spatrick
183e5dd7070Spatrick // If we have an object type, it's because we are in a
184e5dd7070Spatrick // pseudo-destructor-expression or a member access expression, and
185e5dd7070Spatrick // we know what type we're looking for.
186ec727ea7Spatrick QualType SearchType =
187ec727ea7Spatrick ObjectTypePtr ? GetTypeFromParser(ObjectTypePtr) : QualType();
188e5dd7070Spatrick
189ec727ea7Spatrick auto CheckLookupResult = [&](LookupResult &Found) -> ParsedType {
190ec727ea7Spatrick auto IsAcceptableResult = [&](NamedDecl *D) -> bool {
191ec727ea7Spatrick auto *Type = dyn_cast<TypeDecl>(D->getUnderlyingDecl());
192ec727ea7Spatrick if (!Type)
193ec727ea7Spatrick return false;
194e5dd7070Spatrick
195ec727ea7Spatrick if (SearchType.isNull() || SearchType->isDependentType())
196ec727ea7Spatrick return true;
197ec727ea7Spatrick
198ec727ea7Spatrick QualType T = Context.getTypeDeclType(Type);
199ec727ea7Spatrick return Context.hasSameUnqualifiedType(T, SearchType);
200ec727ea7Spatrick };
201ec727ea7Spatrick
202ec727ea7Spatrick unsigned NumAcceptableResults = 0;
203ec727ea7Spatrick for (NamedDecl *D : Found) {
204ec727ea7Spatrick if (IsAcceptableResult(D))
205ec727ea7Spatrick ++NumAcceptableResults;
206ec727ea7Spatrick
207ec727ea7Spatrick // Don't list a class twice in the lookup failure diagnostic if it's
208ec727ea7Spatrick // found by both its injected-class-name and by the name in the enclosing
209ec727ea7Spatrick // scope.
210ec727ea7Spatrick if (auto *RD = dyn_cast<CXXRecordDecl>(D))
211ec727ea7Spatrick if (RD->isInjectedClassName())
212ec727ea7Spatrick D = cast<NamedDecl>(RD->getParent());
213ec727ea7Spatrick
214ec727ea7Spatrick if (FoundDeclSet.insert(D).second)
215ec727ea7Spatrick FoundDecls.push_back(D);
216e5dd7070Spatrick }
217e5dd7070Spatrick
218ec727ea7Spatrick // As an extension, attempt to "fix" an ambiguity by erasing all non-type
219ec727ea7Spatrick // results, and all non-matching results if we have a search type. It's not
220ec727ea7Spatrick // clear what the right behavior is if destructor lookup hits an ambiguity,
221ec727ea7Spatrick // but other compilers do generally accept at least some kinds of
222ec727ea7Spatrick // ambiguity.
223ec727ea7Spatrick if (Found.isAmbiguous() && NumAcceptableResults == 1) {
224ec727ea7Spatrick Diag(NameLoc, diag::ext_dtor_name_ambiguous);
225ec727ea7Spatrick LookupResult::Filter F = Found.makeFilter();
226ec727ea7Spatrick while (F.hasNext()) {
227ec727ea7Spatrick NamedDecl *D = F.next();
228ec727ea7Spatrick if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
229ec727ea7Spatrick Diag(D->getLocation(), diag::note_destructor_type_here)
230ec727ea7Spatrick << Context.getTypeDeclType(TD);
231ec727ea7Spatrick else
232ec727ea7Spatrick Diag(D->getLocation(), diag::note_destructor_nontype_here);
233ec727ea7Spatrick
234ec727ea7Spatrick if (!IsAcceptableResult(D))
235ec727ea7Spatrick F.erase();
236e5dd7070Spatrick }
237ec727ea7Spatrick F.done();
238ec727ea7Spatrick }
239ec727ea7Spatrick
240ec727ea7Spatrick if (Found.isAmbiguous())
241ec727ea7Spatrick Failed = true;
242ec727ea7Spatrick
243ec727ea7Spatrick if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
244ec727ea7Spatrick if (IsAcceptableResult(Type)) {
245ec727ea7Spatrick QualType T = Context.getTypeDeclType(Type);
246ec727ea7Spatrick MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);
247*12c85518Srobert return CreateParsedType(Context.getElaboratedType(ETK_None, nullptr, T),
248ec727ea7Spatrick Context.getTrivialTypeSourceInfo(T, NameLoc));
249ec727ea7Spatrick }
250ec727ea7Spatrick }
251ec727ea7Spatrick
252ec727ea7Spatrick return nullptr;
253ec727ea7Spatrick };
254ec727ea7Spatrick
255ec727ea7Spatrick bool IsDependent = false;
256ec727ea7Spatrick
257ec727ea7Spatrick auto LookupInObjectType = [&]() -> ParsedType {
258ec727ea7Spatrick if (Failed || SearchType.isNull())
259ec727ea7Spatrick return nullptr;
260ec727ea7Spatrick
261ec727ea7Spatrick IsDependent |= SearchType->isDependentType();
262ec727ea7Spatrick
263ec727ea7Spatrick LookupResult Found(*this, &II, NameLoc, LookupDestructorName);
264ec727ea7Spatrick DeclContext *LookupCtx = computeDeclContext(SearchType);
265ec727ea7Spatrick if (!LookupCtx)
266ec727ea7Spatrick return nullptr;
267ec727ea7Spatrick LookupQualifiedName(Found, LookupCtx);
268ec727ea7Spatrick return CheckLookupResult(Found);
269ec727ea7Spatrick };
270ec727ea7Spatrick
271ec727ea7Spatrick auto LookupInNestedNameSpec = [&](CXXScopeSpec &LookupSS) -> ParsedType {
272ec727ea7Spatrick if (Failed)
273ec727ea7Spatrick return nullptr;
274ec727ea7Spatrick
275ec727ea7Spatrick IsDependent |= isDependentScopeSpecifier(LookupSS);
276ec727ea7Spatrick DeclContext *LookupCtx = computeDeclContext(LookupSS, EnteringContext);
277ec727ea7Spatrick if (!LookupCtx)
278ec727ea7Spatrick return nullptr;
279ec727ea7Spatrick
280ec727ea7Spatrick LookupResult Found(*this, &II, NameLoc, LookupDestructorName);
281ec727ea7Spatrick if (RequireCompleteDeclContext(LookupSS, LookupCtx)) {
282ec727ea7Spatrick Failed = true;
283ec727ea7Spatrick return nullptr;
284ec727ea7Spatrick }
285ec727ea7Spatrick LookupQualifiedName(Found, LookupCtx);
286ec727ea7Spatrick return CheckLookupResult(Found);
287ec727ea7Spatrick };
288ec727ea7Spatrick
289ec727ea7Spatrick auto LookupInScope = [&]() -> ParsedType {
290ec727ea7Spatrick if (Failed || !S)
291ec727ea7Spatrick return nullptr;
292ec727ea7Spatrick
293ec727ea7Spatrick LookupResult Found(*this, &II, NameLoc, LookupDestructorName);
294ec727ea7Spatrick LookupName(Found, S);
295ec727ea7Spatrick return CheckLookupResult(Found);
296ec727ea7Spatrick };
297ec727ea7Spatrick
298ec727ea7Spatrick // C++2a [basic.lookup.qual]p6:
299ec727ea7Spatrick // In a qualified-id of the form
300ec727ea7Spatrick //
301ec727ea7Spatrick // nested-name-specifier[opt] type-name :: ~ type-name
302ec727ea7Spatrick //
303ec727ea7Spatrick // the second type-name is looked up in the same scope as the first.
304ec727ea7Spatrick //
305ec727ea7Spatrick // We interpret this as meaning that if you do a dual-scope lookup for the
306ec727ea7Spatrick // first name, you also do a dual-scope lookup for the second name, per
307ec727ea7Spatrick // C++ [basic.lookup.classref]p4:
308ec727ea7Spatrick //
309ec727ea7Spatrick // If the id-expression in a class member access is a qualified-id of the
310ec727ea7Spatrick // form
311ec727ea7Spatrick //
312ec727ea7Spatrick // class-name-or-namespace-name :: ...
313ec727ea7Spatrick //
314ec727ea7Spatrick // the class-name-or-namespace-name following the . or -> is first looked
315ec727ea7Spatrick // up in the class of the object expression and the name, if found, is used.
316ec727ea7Spatrick // Otherwise, it is looked up in the context of the entire
317ec727ea7Spatrick // postfix-expression.
318ec727ea7Spatrick //
319ec727ea7Spatrick // This looks in the same scopes as for an unqualified destructor name:
320ec727ea7Spatrick //
321e5dd7070Spatrick // C++ [basic.lookup.classref]p3:
322e5dd7070Spatrick // If the unqualified-id is ~ type-name, the type-name is looked up
323e5dd7070Spatrick // in the context of the entire postfix-expression. If the type T
324e5dd7070Spatrick // of the object expression is of a class type C, the type-name is
325e5dd7070Spatrick // also looked up in the scope of class C. At least one of the
326ec727ea7Spatrick // lookups shall find a name that refers to cv T.
327ec727ea7Spatrick //
328ec727ea7Spatrick // FIXME: The intent is unclear here. Should type-name::~type-name look in
329ec727ea7Spatrick // the scope anyway if it finds a non-matching name declared in the class?
330ec727ea7Spatrick // If both lookups succeed and find a dependent result, which result should
331ec727ea7Spatrick // we retain? (Same question for p->~type-name().)
332e5dd7070Spatrick
333ec727ea7Spatrick if (NestedNameSpecifier *Prefix =
334ec727ea7Spatrick SS.isSet() ? SS.getScopeRep()->getPrefix() : nullptr) {
335ec727ea7Spatrick // This is
336ec727ea7Spatrick //
337ec727ea7Spatrick // nested-name-specifier type-name :: ~ type-name
338ec727ea7Spatrick //
339ec727ea7Spatrick // Look for the second type-name in the nested-name-specifier.
340ec727ea7Spatrick CXXScopeSpec PrefixSS;
341ec727ea7Spatrick PrefixSS.Adopt(NestedNameSpecifierLoc(Prefix, SS.location_data()));
342ec727ea7Spatrick if (ParsedType T = LookupInNestedNameSpec(PrefixSS))
343ec727ea7Spatrick return T;
344e5dd7070Spatrick } else {
345ec727ea7Spatrick // This is one of
346ec727ea7Spatrick //
347ec727ea7Spatrick // type-name :: ~ type-name
348ec727ea7Spatrick // ~ type-name
349ec727ea7Spatrick //
350ec727ea7Spatrick // Look in the scope and (if any) the object type.
351ec727ea7Spatrick if (ParsedType T = LookupInScope())
352ec727ea7Spatrick return T;
353ec727ea7Spatrick if (ParsedType T = LookupInObjectType())
354ec727ea7Spatrick return T;
355e5dd7070Spatrick }
356e5dd7070Spatrick
357ec727ea7Spatrick if (Failed)
358e5dd7070Spatrick return nullptr;
359e5dd7070Spatrick
360ec727ea7Spatrick if (IsDependent) {
361ec727ea7Spatrick // We didn't find our type, but that's OK: it's dependent anyway.
362e5dd7070Spatrick
363e5dd7070Spatrick // FIXME: What if we have no nested-name-specifier?
364e5dd7070Spatrick QualType T = CheckTypenameType(ETK_None, SourceLocation(),
365e5dd7070Spatrick SS.getWithLocInContext(Context),
366e5dd7070Spatrick II, NameLoc);
367e5dd7070Spatrick return ParsedType::make(T);
368e5dd7070Spatrick }
369e5dd7070Spatrick
370ec727ea7Spatrick // The remaining cases are all non-standard extensions imitating the behavior
371ec727ea7Spatrick // of various other compilers.
372ec727ea7Spatrick unsigned NumNonExtensionDecls = FoundDecls.size();
373ec727ea7Spatrick
374ec727ea7Spatrick if (SS.isSet()) {
375ec727ea7Spatrick // For compatibility with older broken C++ rules and existing code,
376ec727ea7Spatrick //
377ec727ea7Spatrick // nested-name-specifier :: ~ type-name
378ec727ea7Spatrick //
379ec727ea7Spatrick // also looks for type-name within the nested-name-specifier.
380ec727ea7Spatrick if (ParsedType T = LookupInNestedNameSpec(SS)) {
381ec727ea7Spatrick Diag(SS.getEndLoc(), diag::ext_dtor_named_in_wrong_scope)
382ec727ea7Spatrick << SS.getRange()
383ec727ea7Spatrick << FixItHint::CreateInsertion(SS.getEndLoc(),
384ec727ea7Spatrick ("::" + II.getName()).str());
385ec727ea7Spatrick return T;
386e5dd7070Spatrick }
387ec727ea7Spatrick
388ec727ea7Spatrick // For compatibility with other compilers and older versions of Clang,
389ec727ea7Spatrick //
390ec727ea7Spatrick // nested-name-specifier type-name :: ~ type-name
391ec727ea7Spatrick //
392ec727ea7Spatrick // also looks for type-name in the scope. Unfortunately, we can't
393ec727ea7Spatrick // reasonably apply this fallback for dependent nested-name-specifiers.
394ec727ea7Spatrick if (SS.getScopeRep()->getPrefix()) {
395ec727ea7Spatrick if (ParsedType T = LookupInScope()) {
396ec727ea7Spatrick Diag(SS.getEndLoc(), diag::ext_qualified_dtor_named_in_lexical_scope)
397ec727ea7Spatrick << FixItHint::CreateRemoval(SS.getRange());
398ec727ea7Spatrick Diag(FoundDecls.back()->getLocation(), diag::note_destructor_type_here)
399ec727ea7Spatrick << GetTypeFromParser(T);
400ec727ea7Spatrick return T;
401ec727ea7Spatrick }
402ec727ea7Spatrick }
403ec727ea7Spatrick }
404ec727ea7Spatrick
405ec727ea7Spatrick // We didn't find anything matching; tell the user what we did find (if
406ec727ea7Spatrick // anything).
407ec727ea7Spatrick
408ec727ea7Spatrick // Don't tell the user about declarations we shouldn't have found.
409ec727ea7Spatrick FoundDecls.resize(NumNonExtensionDecls);
410ec727ea7Spatrick
411ec727ea7Spatrick // List types before non-types.
412ec727ea7Spatrick std::stable_sort(FoundDecls.begin(), FoundDecls.end(),
413ec727ea7Spatrick [](NamedDecl *A, NamedDecl *B) {
414ec727ea7Spatrick return isa<TypeDecl>(A->getUnderlyingDecl()) >
415ec727ea7Spatrick isa<TypeDecl>(B->getUnderlyingDecl());
416ec727ea7Spatrick });
417ec727ea7Spatrick
418ec727ea7Spatrick // Suggest a fixit to properly name the destroyed type.
419ec727ea7Spatrick auto MakeFixItHint = [&]{
420ec727ea7Spatrick const CXXRecordDecl *Destroyed = nullptr;
421ec727ea7Spatrick // FIXME: If we have a scope specifier, suggest its last component?
422ec727ea7Spatrick if (!SearchType.isNull())
423ec727ea7Spatrick Destroyed = SearchType->getAsCXXRecordDecl();
424ec727ea7Spatrick else if (S)
425ec727ea7Spatrick Destroyed = dyn_cast_or_null<CXXRecordDecl>(S->getEntity());
426ec727ea7Spatrick if (Destroyed)
427ec727ea7Spatrick return FixItHint::CreateReplacement(SourceRange(NameLoc),
428ec727ea7Spatrick Destroyed->getNameAsString());
429ec727ea7Spatrick return FixItHint();
430ec727ea7Spatrick };
431ec727ea7Spatrick
432ec727ea7Spatrick if (FoundDecls.empty()) {
433ec727ea7Spatrick // FIXME: Attempt typo-correction?
434ec727ea7Spatrick Diag(NameLoc, diag::err_undeclared_destructor_name)
435ec727ea7Spatrick << &II << MakeFixItHint();
436ec727ea7Spatrick } else if (!SearchType.isNull() && FoundDecls.size() == 1) {
437ec727ea7Spatrick if (auto *TD = dyn_cast<TypeDecl>(FoundDecls[0]->getUnderlyingDecl())) {
438ec727ea7Spatrick assert(!SearchType.isNull() &&
439ec727ea7Spatrick "should only reject a type result if we have a search type");
440ec727ea7Spatrick QualType T = Context.getTypeDeclType(TD);
441ec727ea7Spatrick Diag(NameLoc, diag::err_destructor_expr_type_mismatch)
442ec727ea7Spatrick << T << SearchType << MakeFixItHint();
443ec727ea7Spatrick } else {
444ec727ea7Spatrick Diag(NameLoc, diag::err_destructor_expr_nontype)
445ec727ea7Spatrick << &II << MakeFixItHint();
446ec727ea7Spatrick }
447ec727ea7Spatrick } else {
448ec727ea7Spatrick Diag(NameLoc, SearchType.isNull() ? diag::err_destructor_name_nontype
449ec727ea7Spatrick : diag::err_destructor_expr_mismatch)
450ec727ea7Spatrick << &II << SearchType << MakeFixItHint();
451ec727ea7Spatrick }
452ec727ea7Spatrick
453ec727ea7Spatrick for (NamedDecl *FoundD : FoundDecls) {
454ec727ea7Spatrick if (auto *TD = dyn_cast<TypeDecl>(FoundD->getUnderlyingDecl()))
455ec727ea7Spatrick Diag(FoundD->getLocation(), diag::note_destructor_type_here)
456ec727ea7Spatrick << Context.getTypeDeclType(TD);
457ec727ea7Spatrick else
458ec727ea7Spatrick Diag(FoundD->getLocation(), diag::note_destructor_nontype_here)
459ec727ea7Spatrick << FoundD;
460e5dd7070Spatrick }
461e5dd7070Spatrick
462e5dd7070Spatrick return nullptr;
463e5dd7070Spatrick }
464e5dd7070Spatrick
getDestructorTypeForDecltype(const DeclSpec & DS,ParsedType ObjectType)465e5dd7070Spatrick ParsedType Sema::getDestructorTypeForDecltype(const DeclSpec &DS,
466e5dd7070Spatrick ParsedType ObjectType) {
467e5dd7070Spatrick if (DS.getTypeSpecType() == DeclSpec::TST_error)
468e5dd7070Spatrick return nullptr;
469e5dd7070Spatrick
470e5dd7070Spatrick if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto) {
471e5dd7070Spatrick Diag(DS.getTypeSpecTypeLoc(), diag::err_decltype_auto_invalid);
472e5dd7070Spatrick return nullptr;
473e5dd7070Spatrick }
474e5dd7070Spatrick
475e5dd7070Spatrick assert(DS.getTypeSpecType() == DeclSpec::TST_decltype &&
476e5dd7070Spatrick "unexpected type in getDestructorType");
477*12c85518Srobert QualType T = BuildDecltypeType(DS.getRepAsExpr());
478e5dd7070Spatrick
479e5dd7070Spatrick // If we know the type of the object, check that the correct destructor
480e5dd7070Spatrick // type was named now; we can give better diagnostics this way.
481e5dd7070Spatrick QualType SearchType = GetTypeFromParser(ObjectType);
482e5dd7070Spatrick if (!SearchType.isNull() && !SearchType->isDependentType() &&
483e5dd7070Spatrick !Context.hasSameUnqualifiedType(T, SearchType)) {
484e5dd7070Spatrick Diag(DS.getTypeSpecTypeLoc(), diag::err_destructor_expr_type_mismatch)
485e5dd7070Spatrick << T << SearchType;
486e5dd7070Spatrick return nullptr;
487e5dd7070Spatrick }
488e5dd7070Spatrick
489e5dd7070Spatrick return ParsedType::make(T);
490e5dd7070Spatrick }
491e5dd7070Spatrick
checkLiteralOperatorId(const CXXScopeSpec & SS,const UnqualifiedId & Name,bool IsUDSuffix)492e5dd7070Spatrick bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
493a9ac8606Spatrick const UnqualifiedId &Name, bool IsUDSuffix) {
494e5dd7070Spatrick assert(Name.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId);
495a9ac8606Spatrick if (!IsUDSuffix) {
496a9ac8606Spatrick // [over.literal] p8
497a9ac8606Spatrick //
498a9ac8606Spatrick // double operator""_Bq(long double); // OK: not a reserved identifier
499a9ac8606Spatrick // double operator"" _Bq(long double); // ill-formed, no diagnostic required
500a9ac8606Spatrick IdentifierInfo *II = Name.Identifier;
501a9ac8606Spatrick ReservedIdentifierStatus Status = II->isReserved(PP.getLangOpts());
502a9ac8606Spatrick SourceLocation Loc = Name.getEndLoc();
503*12c85518Srobert if (isReservedInAllContexts(Status) &&
504a9ac8606Spatrick !PP.getSourceManager().isInSystemHeader(Loc)) {
505a9ac8606Spatrick Diag(Loc, diag::warn_reserved_extern_symbol)
506a9ac8606Spatrick << II << static_cast<int>(Status)
507a9ac8606Spatrick << FixItHint::CreateReplacement(
508a9ac8606Spatrick Name.getSourceRange(),
509a9ac8606Spatrick (StringRef("operator\"\"") + II->getName()).str());
510a9ac8606Spatrick }
511a9ac8606Spatrick }
512e5dd7070Spatrick
513e5dd7070Spatrick if (!SS.isValid())
514e5dd7070Spatrick return false;
515e5dd7070Spatrick
516e5dd7070Spatrick switch (SS.getScopeRep()->getKind()) {
517e5dd7070Spatrick case NestedNameSpecifier::Identifier:
518e5dd7070Spatrick case NestedNameSpecifier::TypeSpec:
519e5dd7070Spatrick case NestedNameSpecifier::TypeSpecWithTemplate:
520e5dd7070Spatrick // Per C++11 [over.literal]p2, literal operators can only be declared at
521e5dd7070Spatrick // namespace scope. Therefore, this unqualified-id cannot name anything.
522e5dd7070Spatrick // Reject it early, because we have no AST representation for this in the
523e5dd7070Spatrick // case where the scope is dependent.
524e5dd7070Spatrick Diag(Name.getBeginLoc(), diag::err_literal_operator_id_outside_namespace)
525e5dd7070Spatrick << SS.getScopeRep();
526e5dd7070Spatrick return true;
527e5dd7070Spatrick
528e5dd7070Spatrick case NestedNameSpecifier::Global:
529e5dd7070Spatrick case NestedNameSpecifier::Super:
530e5dd7070Spatrick case NestedNameSpecifier::Namespace:
531e5dd7070Spatrick case NestedNameSpecifier::NamespaceAlias:
532e5dd7070Spatrick return false;
533e5dd7070Spatrick }
534e5dd7070Spatrick
535e5dd7070Spatrick llvm_unreachable("unknown nested name specifier kind");
536e5dd7070Spatrick }
537e5dd7070Spatrick
538e5dd7070Spatrick /// Build a C++ typeid expression with a type operand.
BuildCXXTypeId(QualType TypeInfoType,SourceLocation TypeidLoc,TypeSourceInfo * Operand,SourceLocation RParenLoc)539e5dd7070Spatrick ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
540e5dd7070Spatrick SourceLocation TypeidLoc,
541e5dd7070Spatrick TypeSourceInfo *Operand,
542e5dd7070Spatrick SourceLocation RParenLoc) {
543e5dd7070Spatrick // C++ [expr.typeid]p4:
544e5dd7070Spatrick // The top-level cv-qualifiers of the lvalue expression or the type-id
545e5dd7070Spatrick // that is the operand of typeid are always ignored.
546e5dd7070Spatrick // If the type of the type-id is a class type or a reference to a class
547e5dd7070Spatrick // type, the class shall be completely-defined.
548e5dd7070Spatrick Qualifiers Quals;
549e5dd7070Spatrick QualType T
550e5dd7070Spatrick = Context.getUnqualifiedArrayType(Operand->getType().getNonReferenceType(),
551e5dd7070Spatrick Quals);
552e5dd7070Spatrick if (T->getAs<RecordType>() &&
553e5dd7070Spatrick RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
554e5dd7070Spatrick return ExprError();
555e5dd7070Spatrick
556e5dd7070Spatrick if (T->isVariablyModifiedType())
557e5dd7070Spatrick return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << T);
558e5dd7070Spatrick
559e5dd7070Spatrick if (CheckQualifiedFunctionForTypeId(T, TypeidLoc))
560e5dd7070Spatrick return ExprError();
561e5dd7070Spatrick
562e5dd7070Spatrick return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand,
563e5dd7070Spatrick SourceRange(TypeidLoc, RParenLoc));
564e5dd7070Spatrick }
565e5dd7070Spatrick
566e5dd7070Spatrick /// Build a C++ typeid expression with an expression operand.
BuildCXXTypeId(QualType TypeInfoType,SourceLocation TypeidLoc,Expr * E,SourceLocation RParenLoc)567e5dd7070Spatrick ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
568e5dd7070Spatrick SourceLocation TypeidLoc,
569e5dd7070Spatrick Expr *E,
570e5dd7070Spatrick SourceLocation RParenLoc) {
571e5dd7070Spatrick bool WasEvaluated = false;
572e5dd7070Spatrick if (E && !E->isTypeDependent()) {
573*12c85518Srobert if (E->hasPlaceholderType()) {
574e5dd7070Spatrick ExprResult result = CheckPlaceholderExpr(E);
575e5dd7070Spatrick if (result.isInvalid()) return ExprError();
576e5dd7070Spatrick E = result.get();
577e5dd7070Spatrick }
578e5dd7070Spatrick
579e5dd7070Spatrick QualType T = E->getType();
580e5dd7070Spatrick if (const RecordType *RecordT = T->getAs<RecordType>()) {
581e5dd7070Spatrick CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl());
582e5dd7070Spatrick // C++ [expr.typeid]p3:
583e5dd7070Spatrick // [...] If the type of the expression is a class type, the class
584e5dd7070Spatrick // shall be completely-defined.
585e5dd7070Spatrick if (RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
586e5dd7070Spatrick return ExprError();
587e5dd7070Spatrick
588e5dd7070Spatrick // C++ [expr.typeid]p3:
589e5dd7070Spatrick // When typeid is applied to an expression other than an glvalue of a
590e5dd7070Spatrick // polymorphic class type [...] [the] expression is an unevaluated
591e5dd7070Spatrick // operand. [...]
592e5dd7070Spatrick if (RecordD->isPolymorphic() && E->isGLValue()) {
593a9ac8606Spatrick if (isUnevaluatedContext()) {
594a9ac8606Spatrick // The operand was processed in unevaluated context, switch the
595a9ac8606Spatrick // context and recheck the subexpression.
596e5dd7070Spatrick ExprResult Result = TransformToPotentiallyEvaluated(E);
597a9ac8606Spatrick if (Result.isInvalid())
598a9ac8606Spatrick return ExprError();
599e5dd7070Spatrick E = Result.get();
600a9ac8606Spatrick }
601e5dd7070Spatrick
602e5dd7070Spatrick // We require a vtable to query the type at run time.
603e5dd7070Spatrick MarkVTableUsed(TypeidLoc, RecordD);
604e5dd7070Spatrick WasEvaluated = true;
605e5dd7070Spatrick }
606e5dd7070Spatrick }
607e5dd7070Spatrick
608e5dd7070Spatrick ExprResult Result = CheckUnevaluatedOperand(E);
609e5dd7070Spatrick if (Result.isInvalid())
610e5dd7070Spatrick return ExprError();
611e5dd7070Spatrick E = Result.get();
612e5dd7070Spatrick
613e5dd7070Spatrick // C++ [expr.typeid]p4:
614e5dd7070Spatrick // [...] If the type of the type-id is a reference to a possibly
615e5dd7070Spatrick // cv-qualified type, the result of the typeid expression refers to a
616e5dd7070Spatrick // std::type_info object representing the cv-unqualified referenced
617e5dd7070Spatrick // type.
618e5dd7070Spatrick Qualifiers Quals;
619e5dd7070Spatrick QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
620e5dd7070Spatrick if (!Context.hasSameType(T, UnqualT)) {
621e5dd7070Spatrick T = UnqualT;
622e5dd7070Spatrick E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).get();
623e5dd7070Spatrick }
624e5dd7070Spatrick }
625e5dd7070Spatrick
626e5dd7070Spatrick if (E->getType()->isVariablyModifiedType())
627e5dd7070Spatrick return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid)
628e5dd7070Spatrick << E->getType());
629e5dd7070Spatrick else if (!inTemplateInstantiation() &&
630e5dd7070Spatrick E->HasSideEffects(Context, WasEvaluated)) {
631e5dd7070Spatrick // The expression operand for typeid is in an unevaluated expression
632e5dd7070Spatrick // context, so side effects could result in unintended consequences.
633e5dd7070Spatrick Diag(E->getExprLoc(), WasEvaluated
634e5dd7070Spatrick ? diag::warn_side_effects_typeid
635e5dd7070Spatrick : diag::warn_side_effects_unevaluated_context);
636e5dd7070Spatrick }
637e5dd7070Spatrick
638e5dd7070Spatrick return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E,
639e5dd7070Spatrick SourceRange(TypeidLoc, RParenLoc));
640e5dd7070Spatrick }
641e5dd7070Spatrick
642e5dd7070Spatrick /// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
643e5dd7070Spatrick ExprResult
ActOnCXXTypeid(SourceLocation OpLoc,SourceLocation LParenLoc,bool isType,void * TyOrExpr,SourceLocation RParenLoc)644e5dd7070Spatrick Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
645e5dd7070Spatrick bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
646e5dd7070Spatrick // typeid is not supported in OpenCL.
647e5dd7070Spatrick if (getLangOpts().OpenCLCPlusPlus) {
648e5dd7070Spatrick return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported)
649e5dd7070Spatrick << "typeid");
650e5dd7070Spatrick }
651e5dd7070Spatrick
652e5dd7070Spatrick // Find the std::type_info type.
653e5dd7070Spatrick if (!getStdNamespace())
654e5dd7070Spatrick return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
655e5dd7070Spatrick
656e5dd7070Spatrick if (!CXXTypeInfoDecl) {
657e5dd7070Spatrick IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
658e5dd7070Spatrick LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
659e5dd7070Spatrick LookupQualifiedName(R, getStdNamespace());
660e5dd7070Spatrick CXXTypeInfoDecl = R.getAsSingle<RecordDecl>();
661e5dd7070Spatrick // Microsoft's typeinfo doesn't have type_info in std but in the global
662e5dd7070Spatrick // namespace if _HAS_EXCEPTIONS is defined to 0. See PR13153.
663e5dd7070Spatrick if (!CXXTypeInfoDecl && LangOpts.MSVCCompat) {
664e5dd7070Spatrick LookupQualifiedName(R, Context.getTranslationUnitDecl());
665e5dd7070Spatrick CXXTypeInfoDecl = R.getAsSingle<RecordDecl>();
666e5dd7070Spatrick }
667e5dd7070Spatrick if (!CXXTypeInfoDecl)
668e5dd7070Spatrick return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
669e5dd7070Spatrick }
670e5dd7070Spatrick
671e5dd7070Spatrick if (!getLangOpts().RTTI) {
672e5dd7070Spatrick return ExprError(Diag(OpLoc, diag::err_no_typeid_with_fno_rtti));
673e5dd7070Spatrick }
674e5dd7070Spatrick
675e5dd7070Spatrick QualType TypeInfoType = Context.getTypeDeclType(CXXTypeInfoDecl);
676e5dd7070Spatrick
677e5dd7070Spatrick if (isType) {
678e5dd7070Spatrick // The operand is a type; handle it as such.
679e5dd7070Spatrick TypeSourceInfo *TInfo = nullptr;
680e5dd7070Spatrick QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
681e5dd7070Spatrick &TInfo);
682e5dd7070Spatrick if (T.isNull())
683e5dd7070Spatrick return ExprError();
684e5dd7070Spatrick
685e5dd7070Spatrick if (!TInfo)
686e5dd7070Spatrick TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
687e5dd7070Spatrick
688e5dd7070Spatrick return BuildCXXTypeId(TypeInfoType, OpLoc, TInfo, RParenLoc);
689e5dd7070Spatrick }
690e5dd7070Spatrick
691e5dd7070Spatrick // The operand is an expression.
692a9ac8606Spatrick ExprResult Result =
693a9ac8606Spatrick BuildCXXTypeId(TypeInfoType, OpLoc, (Expr *)TyOrExpr, RParenLoc);
694a9ac8606Spatrick
695a9ac8606Spatrick if (!getLangOpts().RTTIData && !Result.isInvalid())
696a9ac8606Spatrick if (auto *CTE = dyn_cast<CXXTypeidExpr>(Result.get()))
697a9ac8606Spatrick if (CTE->isPotentiallyEvaluated() && !CTE->isMostDerived(Context))
698a9ac8606Spatrick Diag(OpLoc, diag::warn_no_typeid_with_rtti_disabled)
699a9ac8606Spatrick << (getDiagnostics().getDiagnosticOptions().getFormat() ==
700a9ac8606Spatrick DiagnosticOptions::MSVC);
701a9ac8606Spatrick return Result;
702e5dd7070Spatrick }
703e5dd7070Spatrick
704e5dd7070Spatrick /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
705e5dd7070Spatrick /// a single GUID.
706e5dd7070Spatrick static void
getUuidAttrOfType(Sema & SemaRef,QualType QT,llvm::SmallSetVector<const UuidAttr *,1> & UuidAttrs)707e5dd7070Spatrick getUuidAttrOfType(Sema &SemaRef, QualType QT,
708e5dd7070Spatrick llvm::SmallSetVector<const UuidAttr *, 1> &UuidAttrs) {
709e5dd7070Spatrick // Optionally remove one level of pointer, reference or array indirection.
710e5dd7070Spatrick const Type *Ty = QT.getTypePtr();
711e5dd7070Spatrick if (QT->isPointerType() || QT->isReferenceType())
712e5dd7070Spatrick Ty = QT->getPointeeType().getTypePtr();
713e5dd7070Spatrick else if (QT->isArrayType())
714e5dd7070Spatrick Ty = Ty->getBaseElementTypeUnsafe();
715e5dd7070Spatrick
716e5dd7070Spatrick const auto *TD = Ty->getAsTagDecl();
717e5dd7070Spatrick if (!TD)
718e5dd7070Spatrick return;
719e5dd7070Spatrick
720e5dd7070Spatrick if (const auto *Uuid = TD->getMostRecentDecl()->getAttr<UuidAttr>()) {
721e5dd7070Spatrick UuidAttrs.insert(Uuid);
722e5dd7070Spatrick return;
723e5dd7070Spatrick }
724e5dd7070Spatrick
725e5dd7070Spatrick // __uuidof can grab UUIDs from template arguments.
726e5dd7070Spatrick if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(TD)) {
727e5dd7070Spatrick const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
728e5dd7070Spatrick for (const TemplateArgument &TA : TAL.asArray()) {
729e5dd7070Spatrick const UuidAttr *UuidForTA = nullptr;
730e5dd7070Spatrick if (TA.getKind() == TemplateArgument::Type)
731e5dd7070Spatrick getUuidAttrOfType(SemaRef, TA.getAsType(), UuidAttrs);
732e5dd7070Spatrick else if (TA.getKind() == TemplateArgument::Declaration)
733e5dd7070Spatrick getUuidAttrOfType(SemaRef, TA.getAsDecl()->getType(), UuidAttrs);
734e5dd7070Spatrick
735e5dd7070Spatrick if (UuidForTA)
736e5dd7070Spatrick UuidAttrs.insert(UuidForTA);
737e5dd7070Spatrick }
738e5dd7070Spatrick }
739e5dd7070Spatrick }
740e5dd7070Spatrick
741e5dd7070Spatrick /// Build a Microsoft __uuidof expression with a type operand.
BuildCXXUuidof(QualType Type,SourceLocation TypeidLoc,TypeSourceInfo * Operand,SourceLocation RParenLoc)742ec727ea7Spatrick ExprResult Sema::BuildCXXUuidof(QualType Type,
743e5dd7070Spatrick SourceLocation TypeidLoc,
744e5dd7070Spatrick TypeSourceInfo *Operand,
745e5dd7070Spatrick SourceLocation RParenLoc) {
746ec727ea7Spatrick MSGuidDecl *Guid = nullptr;
747e5dd7070Spatrick if (!Operand->getType()->isDependentType()) {
748e5dd7070Spatrick llvm::SmallSetVector<const UuidAttr *, 1> UuidAttrs;
749e5dd7070Spatrick getUuidAttrOfType(*this, Operand->getType(), UuidAttrs);
750e5dd7070Spatrick if (UuidAttrs.empty())
751e5dd7070Spatrick return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
752e5dd7070Spatrick if (UuidAttrs.size() > 1)
753e5dd7070Spatrick return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
754ec727ea7Spatrick Guid = UuidAttrs.back()->getGuidDecl();
755e5dd7070Spatrick }
756e5dd7070Spatrick
757ec727ea7Spatrick return new (Context)
758ec727ea7Spatrick CXXUuidofExpr(Type, Operand, Guid, SourceRange(TypeidLoc, RParenLoc));
759e5dd7070Spatrick }
760e5dd7070Spatrick
761e5dd7070Spatrick /// Build a Microsoft __uuidof expression with an expression operand.
BuildCXXUuidof(QualType Type,SourceLocation TypeidLoc,Expr * E,SourceLocation RParenLoc)762ec727ea7Spatrick ExprResult Sema::BuildCXXUuidof(QualType Type, SourceLocation TypeidLoc,
763ec727ea7Spatrick Expr *E, SourceLocation RParenLoc) {
764ec727ea7Spatrick MSGuidDecl *Guid = nullptr;
765e5dd7070Spatrick if (!E->getType()->isDependentType()) {
766e5dd7070Spatrick if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
767ec727ea7Spatrick // A null pointer results in {00000000-0000-0000-0000-000000000000}.
768ec727ea7Spatrick Guid = Context.getMSGuidDecl(MSGuidDecl::Parts{});
769e5dd7070Spatrick } else {
770e5dd7070Spatrick llvm::SmallSetVector<const UuidAttr *, 1> UuidAttrs;
771e5dd7070Spatrick getUuidAttrOfType(*this, E->getType(), UuidAttrs);
772e5dd7070Spatrick if (UuidAttrs.empty())
773e5dd7070Spatrick return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
774e5dd7070Spatrick if (UuidAttrs.size() > 1)
775e5dd7070Spatrick return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
776ec727ea7Spatrick Guid = UuidAttrs.back()->getGuidDecl();
777e5dd7070Spatrick }
778e5dd7070Spatrick }
779e5dd7070Spatrick
780ec727ea7Spatrick return new (Context)
781ec727ea7Spatrick CXXUuidofExpr(Type, E, Guid, SourceRange(TypeidLoc, RParenLoc));
782e5dd7070Spatrick }
783e5dd7070Spatrick
784e5dd7070Spatrick /// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression);
785e5dd7070Spatrick ExprResult
ActOnCXXUuidof(SourceLocation OpLoc,SourceLocation LParenLoc,bool isType,void * TyOrExpr,SourceLocation RParenLoc)786e5dd7070Spatrick Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc,
787e5dd7070Spatrick bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
788ec727ea7Spatrick QualType GuidType = Context.getMSGuidType();
789ec727ea7Spatrick GuidType.addConst();
790e5dd7070Spatrick
791e5dd7070Spatrick if (isType) {
792e5dd7070Spatrick // The operand is a type; handle it as such.
793e5dd7070Spatrick TypeSourceInfo *TInfo = nullptr;
794e5dd7070Spatrick QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
795e5dd7070Spatrick &TInfo);
796e5dd7070Spatrick if (T.isNull())
797e5dd7070Spatrick return ExprError();
798e5dd7070Spatrick
799e5dd7070Spatrick if (!TInfo)
800e5dd7070Spatrick TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
801e5dd7070Spatrick
802e5dd7070Spatrick return BuildCXXUuidof(GuidType, OpLoc, TInfo, RParenLoc);
803e5dd7070Spatrick }
804e5dd7070Spatrick
805e5dd7070Spatrick // The operand is an expression.
806e5dd7070Spatrick return BuildCXXUuidof(GuidType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
807e5dd7070Spatrick }
808e5dd7070Spatrick
809e5dd7070Spatrick /// ActOnCXXBoolLiteral - Parse {true,false} literals.
810e5dd7070Spatrick ExprResult
ActOnCXXBoolLiteral(SourceLocation OpLoc,tok::TokenKind Kind)811e5dd7070Spatrick Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
812e5dd7070Spatrick assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
813e5dd7070Spatrick "Unknown C++ Boolean value!");
814e5dd7070Spatrick return new (Context)
815e5dd7070Spatrick CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
816e5dd7070Spatrick }
817e5dd7070Spatrick
818e5dd7070Spatrick /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
819e5dd7070Spatrick ExprResult
ActOnCXXNullPtrLiteral(SourceLocation Loc)820e5dd7070Spatrick Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
821e5dd7070Spatrick return new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc);
822e5dd7070Spatrick }
823e5dd7070Spatrick
824e5dd7070Spatrick /// ActOnCXXThrow - Parse throw expressions.
825e5dd7070Spatrick ExprResult
ActOnCXXThrow(Scope * S,SourceLocation OpLoc,Expr * Ex)826e5dd7070Spatrick Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) {
827e5dd7070Spatrick bool IsThrownVarInScope = false;
828e5dd7070Spatrick if (Ex) {
829e5dd7070Spatrick // C++0x [class.copymove]p31:
830e5dd7070Spatrick // When certain criteria are met, an implementation is allowed to omit the
831e5dd7070Spatrick // copy/move construction of a class object [...]
832e5dd7070Spatrick //
833e5dd7070Spatrick // - in a throw-expression, when the operand is the name of a
834e5dd7070Spatrick // non-volatile automatic object (other than a function or catch-
835e5dd7070Spatrick // clause parameter) whose scope does not extend beyond the end of the
836e5dd7070Spatrick // innermost enclosing try-block (if there is one), the copy/move
837e5dd7070Spatrick // operation from the operand to the exception object (15.1) can be
838e5dd7070Spatrick // omitted by constructing the automatic object directly into the
839e5dd7070Spatrick // exception object
840e5dd7070Spatrick if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex->IgnoreParens()))
841e5dd7070Spatrick if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
842e5dd7070Spatrick if (Var->hasLocalStorage() && !Var->getType().isVolatileQualified()) {
843e5dd7070Spatrick for( ; S; S = S->getParent()) {
844e5dd7070Spatrick if (S->isDeclScope(Var)) {
845e5dd7070Spatrick IsThrownVarInScope = true;
846e5dd7070Spatrick break;
847e5dd7070Spatrick }
848e5dd7070Spatrick
849*12c85518Srobert // FIXME: Many of the scope checks here seem incorrect.
850e5dd7070Spatrick if (S->getFlags() &
851e5dd7070Spatrick (Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
852*12c85518Srobert Scope::ObjCMethodScope | Scope::TryScope))
853e5dd7070Spatrick break;
854e5dd7070Spatrick }
855e5dd7070Spatrick }
856e5dd7070Spatrick }
857e5dd7070Spatrick }
858e5dd7070Spatrick
859e5dd7070Spatrick return BuildCXXThrow(OpLoc, Ex, IsThrownVarInScope);
860e5dd7070Spatrick }
861e5dd7070Spatrick
BuildCXXThrow(SourceLocation OpLoc,Expr * Ex,bool IsThrownVarInScope)862e5dd7070Spatrick ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
863e5dd7070Spatrick bool IsThrownVarInScope) {
864e5dd7070Spatrick // Don't report an error if 'throw' is used in system headers.
865e5dd7070Spatrick if (!getLangOpts().CXXExceptions &&
866e5dd7070Spatrick !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) {
867e5dd7070Spatrick // Delay error emission for the OpenMP device code.
868e5dd7070Spatrick targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw";
869e5dd7070Spatrick }
870e5dd7070Spatrick
871e5dd7070Spatrick // Exceptions aren't allowed in CUDA device code.
872e5dd7070Spatrick if (getLangOpts().CUDA)
873e5dd7070Spatrick CUDADiagIfDeviceCode(OpLoc, diag::err_cuda_device_exceptions)
874e5dd7070Spatrick << "throw" << CurrentCUDATarget();
875e5dd7070Spatrick
876e5dd7070Spatrick if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
877e5dd7070Spatrick Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw";
878e5dd7070Spatrick
879e5dd7070Spatrick if (Ex && !Ex->isTypeDependent()) {
880e5dd7070Spatrick // Initialize the exception result. This implicitly weeds out
881e5dd7070Spatrick // abstract types or types with inaccessible copy constructors.
882e5dd7070Spatrick
883e5dd7070Spatrick // C++0x [class.copymove]p31:
884e5dd7070Spatrick // When certain criteria are met, an implementation is allowed to omit the
885e5dd7070Spatrick // copy/move construction of a class object [...]
886e5dd7070Spatrick //
887e5dd7070Spatrick // - in a throw-expression, when the operand is the name of a
888e5dd7070Spatrick // non-volatile automatic object (other than a function or
889e5dd7070Spatrick // catch-clause
890e5dd7070Spatrick // parameter) whose scope does not extend beyond the end of the
891e5dd7070Spatrick // innermost enclosing try-block (if there is one), the copy/move
892e5dd7070Spatrick // operation from the operand to the exception object (15.1) can be
893e5dd7070Spatrick // omitted by constructing the automatic object directly into the
894e5dd7070Spatrick // exception object
895a9ac8606Spatrick NamedReturnInfo NRInfo =
896a9ac8606Spatrick IsThrownVarInScope ? getNamedReturnInfo(Ex) : NamedReturnInfo();
897e5dd7070Spatrick
898a9ac8606Spatrick QualType ExceptionObjectTy = Context.getExceptionObjectType(Ex->getType());
899a9ac8606Spatrick if (CheckCXXThrowOperand(OpLoc, ExceptionObjectTy, Ex))
900a9ac8606Spatrick return ExprError();
901a9ac8606Spatrick
902a9ac8606Spatrick InitializedEntity Entity =
903a9ac8606Spatrick InitializedEntity::InitializeException(OpLoc, ExceptionObjectTy);
904a9ac8606Spatrick ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRInfo, Ex);
905e5dd7070Spatrick if (Res.isInvalid())
906e5dd7070Spatrick return ExprError();
907e5dd7070Spatrick Ex = Res.get();
908e5dd7070Spatrick }
909e5dd7070Spatrick
910a9ac8606Spatrick // PPC MMA non-pointer types are not allowed as throw expr types.
911a9ac8606Spatrick if (Ex && Context.getTargetInfo().getTriple().isPPC64())
912a9ac8606Spatrick CheckPPCMMAType(Ex->getType(), Ex->getBeginLoc());
913a9ac8606Spatrick
914e5dd7070Spatrick return new (Context)
915e5dd7070Spatrick CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope);
916e5dd7070Spatrick }
917e5dd7070Spatrick
918e5dd7070Spatrick static void
collectPublicBases(CXXRecordDecl * RD,llvm::DenseMap<CXXRecordDecl *,unsigned> & SubobjectsSeen,llvm::SmallPtrSetImpl<CXXRecordDecl * > & VBases,llvm::SetVector<CXXRecordDecl * > & PublicSubobjectsSeen,bool ParentIsPublic)919e5dd7070Spatrick collectPublicBases(CXXRecordDecl *RD,
920e5dd7070Spatrick llvm::DenseMap<CXXRecordDecl *, unsigned> &SubobjectsSeen,
921e5dd7070Spatrick llvm::SmallPtrSetImpl<CXXRecordDecl *> &VBases,
922e5dd7070Spatrick llvm::SetVector<CXXRecordDecl *> &PublicSubobjectsSeen,
923e5dd7070Spatrick bool ParentIsPublic) {
924e5dd7070Spatrick for (const CXXBaseSpecifier &BS : RD->bases()) {
925e5dd7070Spatrick CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl();
926e5dd7070Spatrick bool NewSubobject;
927e5dd7070Spatrick // Virtual bases constitute the same subobject. Non-virtual bases are
928e5dd7070Spatrick // always distinct subobjects.
929e5dd7070Spatrick if (BS.isVirtual())
930e5dd7070Spatrick NewSubobject = VBases.insert(BaseDecl).second;
931e5dd7070Spatrick else
932e5dd7070Spatrick NewSubobject = true;
933e5dd7070Spatrick
934e5dd7070Spatrick if (NewSubobject)
935e5dd7070Spatrick ++SubobjectsSeen[BaseDecl];
936e5dd7070Spatrick
937e5dd7070Spatrick // Only add subobjects which have public access throughout the entire chain.
938e5dd7070Spatrick bool PublicPath = ParentIsPublic && BS.getAccessSpecifier() == AS_public;
939e5dd7070Spatrick if (PublicPath)
940e5dd7070Spatrick PublicSubobjectsSeen.insert(BaseDecl);
941e5dd7070Spatrick
942e5dd7070Spatrick // Recurse on to each base subobject.
943e5dd7070Spatrick collectPublicBases(BaseDecl, SubobjectsSeen, VBases, PublicSubobjectsSeen,
944e5dd7070Spatrick PublicPath);
945e5dd7070Spatrick }
946e5dd7070Spatrick }
947e5dd7070Spatrick
getUnambiguousPublicSubobjects(CXXRecordDecl * RD,llvm::SmallVectorImpl<CXXRecordDecl * > & Objects)948e5dd7070Spatrick static void getUnambiguousPublicSubobjects(
949e5dd7070Spatrick CXXRecordDecl *RD, llvm::SmallVectorImpl<CXXRecordDecl *> &Objects) {
950e5dd7070Spatrick llvm::DenseMap<CXXRecordDecl *, unsigned> SubobjectsSeen;
951e5dd7070Spatrick llvm::SmallSet<CXXRecordDecl *, 2> VBases;
952e5dd7070Spatrick llvm::SetVector<CXXRecordDecl *> PublicSubobjectsSeen;
953e5dd7070Spatrick SubobjectsSeen[RD] = 1;
954e5dd7070Spatrick PublicSubobjectsSeen.insert(RD);
955e5dd7070Spatrick collectPublicBases(RD, SubobjectsSeen, VBases, PublicSubobjectsSeen,
956e5dd7070Spatrick /*ParentIsPublic=*/true);
957e5dd7070Spatrick
958e5dd7070Spatrick for (CXXRecordDecl *PublicSubobject : PublicSubobjectsSeen) {
959e5dd7070Spatrick // Skip ambiguous objects.
960e5dd7070Spatrick if (SubobjectsSeen[PublicSubobject] > 1)
961e5dd7070Spatrick continue;
962e5dd7070Spatrick
963e5dd7070Spatrick Objects.push_back(PublicSubobject);
964e5dd7070Spatrick }
965e5dd7070Spatrick }
966e5dd7070Spatrick
967e5dd7070Spatrick /// CheckCXXThrowOperand - Validate the operand of a throw.
CheckCXXThrowOperand(SourceLocation ThrowLoc,QualType ExceptionObjectTy,Expr * E)968e5dd7070Spatrick bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc,
969e5dd7070Spatrick QualType ExceptionObjectTy, Expr *E) {
970e5dd7070Spatrick // If the type of the exception would be an incomplete type or a pointer
971e5dd7070Spatrick // to an incomplete type other than (cv) void the program is ill-formed.
972e5dd7070Spatrick QualType Ty = ExceptionObjectTy;
973e5dd7070Spatrick bool isPointer = false;
974e5dd7070Spatrick if (const PointerType* Ptr = Ty->getAs<PointerType>()) {
975e5dd7070Spatrick Ty = Ptr->getPointeeType();
976e5dd7070Spatrick isPointer = true;
977e5dd7070Spatrick }
978e5dd7070Spatrick if (!isPointer || !Ty->isVoidType()) {
979e5dd7070Spatrick if (RequireCompleteType(ThrowLoc, Ty,
980e5dd7070Spatrick isPointer ? diag::err_throw_incomplete_ptr
981e5dd7070Spatrick : diag::err_throw_incomplete,
982e5dd7070Spatrick E->getSourceRange()))
983e5dd7070Spatrick return true;
984e5dd7070Spatrick
985ec727ea7Spatrick if (!isPointer && Ty->isSizelessType()) {
986ec727ea7Spatrick Diag(ThrowLoc, diag::err_throw_sizeless) << Ty << E->getSourceRange();
987ec727ea7Spatrick return true;
988ec727ea7Spatrick }
989ec727ea7Spatrick
990e5dd7070Spatrick if (RequireNonAbstractType(ThrowLoc, ExceptionObjectTy,
991e5dd7070Spatrick diag::err_throw_abstract_type, E))
992e5dd7070Spatrick return true;
993e5dd7070Spatrick }
994e5dd7070Spatrick
995e5dd7070Spatrick // If the exception has class type, we need additional handling.
996e5dd7070Spatrick CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
997e5dd7070Spatrick if (!RD)
998e5dd7070Spatrick return false;
999e5dd7070Spatrick
1000e5dd7070Spatrick // If we are throwing a polymorphic class type or pointer thereof,
1001e5dd7070Spatrick // exception handling will make use of the vtable.
1002e5dd7070Spatrick MarkVTableUsed(ThrowLoc, RD);
1003e5dd7070Spatrick
1004e5dd7070Spatrick // If a pointer is thrown, the referenced object will not be destroyed.
1005e5dd7070Spatrick if (isPointer)
1006e5dd7070Spatrick return false;
1007e5dd7070Spatrick
1008e5dd7070Spatrick // If the class has a destructor, we must be able to call it.
1009e5dd7070Spatrick if (!RD->hasIrrelevantDestructor()) {
1010e5dd7070Spatrick if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) {
1011e5dd7070Spatrick MarkFunctionReferenced(E->getExprLoc(), Destructor);
1012e5dd7070Spatrick CheckDestructorAccess(E->getExprLoc(), Destructor,
1013e5dd7070Spatrick PDiag(diag::err_access_dtor_exception) << Ty);
1014e5dd7070Spatrick if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
1015e5dd7070Spatrick return true;
1016e5dd7070Spatrick }
1017e5dd7070Spatrick }
1018e5dd7070Spatrick
1019e5dd7070Spatrick // The MSVC ABI creates a list of all types which can catch the exception
1020e5dd7070Spatrick // object. This list also references the appropriate copy constructor to call
1021e5dd7070Spatrick // if the object is caught by value and has a non-trivial copy constructor.
1022e5dd7070Spatrick if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
1023e5dd7070Spatrick // We are only interested in the public, unambiguous bases contained within
1024e5dd7070Spatrick // the exception object. Bases which are ambiguous or otherwise
1025e5dd7070Spatrick // inaccessible are not catchable types.
1026e5dd7070Spatrick llvm::SmallVector<CXXRecordDecl *, 2> UnambiguousPublicSubobjects;
1027e5dd7070Spatrick getUnambiguousPublicSubobjects(RD, UnambiguousPublicSubobjects);
1028e5dd7070Spatrick
1029e5dd7070Spatrick for (CXXRecordDecl *Subobject : UnambiguousPublicSubobjects) {
1030e5dd7070Spatrick // Attempt to lookup the copy constructor. Various pieces of machinery
1031e5dd7070Spatrick // will spring into action, like template instantiation, which means this
1032e5dd7070Spatrick // cannot be a simple walk of the class's decls. Instead, we must perform
1033e5dd7070Spatrick // lookup and overload resolution.
1034e5dd7070Spatrick CXXConstructorDecl *CD = LookupCopyingConstructor(Subobject, 0);
1035e5dd7070Spatrick if (!CD || CD->isDeleted())
1036e5dd7070Spatrick continue;
1037e5dd7070Spatrick
1038e5dd7070Spatrick // Mark the constructor referenced as it is used by this throw expression.
1039e5dd7070Spatrick MarkFunctionReferenced(E->getExprLoc(), CD);
1040e5dd7070Spatrick
1041e5dd7070Spatrick // Skip this copy constructor if it is trivial, we don't need to record it
1042e5dd7070Spatrick // in the catchable type data.
1043e5dd7070Spatrick if (CD->isTrivial())
1044e5dd7070Spatrick continue;
1045e5dd7070Spatrick
1046e5dd7070Spatrick // The copy constructor is non-trivial, create a mapping from this class
1047e5dd7070Spatrick // type to this constructor.
1048e5dd7070Spatrick // N.B. The selection of copy constructor is not sensitive to this
1049e5dd7070Spatrick // particular throw-site. Lookup will be performed at the catch-site to
1050e5dd7070Spatrick // ensure that the copy constructor is, in fact, accessible (via
1051e5dd7070Spatrick // friendship or any other means).
1052e5dd7070Spatrick Context.addCopyConstructorForExceptionObject(Subobject, CD);
1053e5dd7070Spatrick
1054e5dd7070Spatrick // We don't keep the instantiated default argument expressions around so
1055e5dd7070Spatrick // we must rebuild them here.
1056e5dd7070Spatrick for (unsigned I = 1, E = CD->getNumParams(); I != E; ++I) {
1057e5dd7070Spatrick if (CheckCXXDefaultArgExpr(ThrowLoc, CD, CD->getParamDecl(I)))
1058e5dd7070Spatrick return true;
1059e5dd7070Spatrick }
1060e5dd7070Spatrick }
1061e5dd7070Spatrick }
1062e5dd7070Spatrick
1063e5dd7070Spatrick // Under the Itanium C++ ABI, memory for the exception object is allocated by
1064e5dd7070Spatrick // the runtime with no ability for the compiler to request additional
1065e5dd7070Spatrick // alignment. Warn if the exception type requires alignment beyond the minimum
1066e5dd7070Spatrick // guaranteed by the target C++ runtime.
1067e5dd7070Spatrick if (Context.getTargetInfo().getCXXABI().isItaniumFamily()) {
1068e5dd7070Spatrick CharUnits TypeAlign = Context.getTypeAlignInChars(Ty);
1069e5dd7070Spatrick CharUnits ExnObjAlign = Context.getExnObjectAlignment();
1070e5dd7070Spatrick if (ExnObjAlign < TypeAlign) {
1071e5dd7070Spatrick Diag(ThrowLoc, diag::warn_throw_underaligned_obj);
1072e5dd7070Spatrick Diag(ThrowLoc, diag::note_throw_underaligned_obj)
1073e5dd7070Spatrick << Ty << (unsigned)TypeAlign.getQuantity()
1074e5dd7070Spatrick << (unsigned)ExnObjAlign.getQuantity();
1075e5dd7070Spatrick }
1076e5dd7070Spatrick }
1077e5dd7070Spatrick
1078e5dd7070Spatrick return false;
1079e5dd7070Spatrick }
1080e5dd7070Spatrick
adjustCVQualifiersForCXXThisWithinLambda(ArrayRef<FunctionScopeInfo * > FunctionScopes,QualType ThisTy,DeclContext * CurSemaContext,ASTContext & ASTCtx)1081e5dd7070Spatrick static QualType adjustCVQualifiersForCXXThisWithinLambda(
1082e5dd7070Spatrick ArrayRef<FunctionScopeInfo *> FunctionScopes, QualType ThisTy,
1083e5dd7070Spatrick DeclContext *CurSemaContext, ASTContext &ASTCtx) {
1084e5dd7070Spatrick
1085e5dd7070Spatrick QualType ClassType = ThisTy->getPointeeType();
1086e5dd7070Spatrick LambdaScopeInfo *CurLSI = nullptr;
1087e5dd7070Spatrick DeclContext *CurDC = CurSemaContext;
1088e5dd7070Spatrick
1089e5dd7070Spatrick // Iterate through the stack of lambdas starting from the innermost lambda to
1090e5dd7070Spatrick // the outermost lambda, checking if '*this' is ever captured by copy - since
1091e5dd7070Spatrick // that could change the cv-qualifiers of the '*this' object.
1092e5dd7070Spatrick // The object referred to by '*this' starts out with the cv-qualifiers of its
1093e5dd7070Spatrick // member function. We then start with the innermost lambda and iterate
1094e5dd7070Spatrick // outward checking to see if any lambda performs a by-copy capture of '*this'
1095e5dd7070Spatrick // - and if so, any nested lambda must respect the 'constness' of that
1096e5dd7070Spatrick // capturing lamdbda's call operator.
1097e5dd7070Spatrick //
1098e5dd7070Spatrick
1099e5dd7070Spatrick // Since the FunctionScopeInfo stack is representative of the lexical
1100e5dd7070Spatrick // nesting of the lambda expressions during initial parsing (and is the best
1101e5dd7070Spatrick // place for querying information about captures about lambdas that are
1102e5dd7070Spatrick // partially processed) and perhaps during instantiation of function templates
1103e5dd7070Spatrick // that contain lambda expressions that need to be transformed BUT not
1104e5dd7070Spatrick // necessarily during instantiation of a nested generic lambda's function call
1105e5dd7070Spatrick // operator (which might even be instantiated at the end of the TU) - at which
1106e5dd7070Spatrick // time the DeclContext tree is mature enough to query capture information
1107e5dd7070Spatrick // reliably - we use a two pronged approach to walk through all the lexically
1108e5dd7070Spatrick // enclosing lambda expressions:
1109e5dd7070Spatrick //
1110e5dd7070Spatrick // 1) Climb down the FunctionScopeInfo stack as long as each item represents
1111e5dd7070Spatrick // a Lambda (i.e. LambdaScopeInfo) AND each LSI's 'closure-type' is lexically
1112e5dd7070Spatrick // enclosed by the call-operator of the LSI below it on the stack (while
1113e5dd7070Spatrick // tracking the enclosing DC for step 2 if needed). Note the topmost LSI on
1114e5dd7070Spatrick // the stack represents the innermost lambda.
1115e5dd7070Spatrick //
1116e5dd7070Spatrick // 2) If we run out of enclosing LSI's, check if the enclosing DeclContext
1117e5dd7070Spatrick // represents a lambda's call operator. If it does, we must be instantiating
1118e5dd7070Spatrick // a generic lambda's call operator (represented by the Current LSI, and
1119e5dd7070Spatrick // should be the only scenario where an inconsistency between the LSI and the
1120e5dd7070Spatrick // DeclContext should occur), so climb out the DeclContexts if they
1121e5dd7070Spatrick // represent lambdas, while querying the corresponding closure types
1122e5dd7070Spatrick // regarding capture information.
1123e5dd7070Spatrick
1124e5dd7070Spatrick // 1) Climb down the function scope info stack.
1125e5dd7070Spatrick for (int I = FunctionScopes.size();
1126e5dd7070Spatrick I-- && isa<LambdaScopeInfo>(FunctionScopes[I]) &&
1127e5dd7070Spatrick (!CurLSI || !CurLSI->Lambda || CurLSI->Lambda->getDeclContext() ==
1128e5dd7070Spatrick cast<LambdaScopeInfo>(FunctionScopes[I])->CallOperator);
1129e5dd7070Spatrick CurDC = getLambdaAwareParentOfDeclContext(CurDC)) {
1130e5dd7070Spatrick CurLSI = cast<LambdaScopeInfo>(FunctionScopes[I]);
1131e5dd7070Spatrick
1132e5dd7070Spatrick if (!CurLSI->isCXXThisCaptured())
1133e5dd7070Spatrick continue;
1134e5dd7070Spatrick
1135e5dd7070Spatrick auto C = CurLSI->getCXXThisCapture();
1136e5dd7070Spatrick
1137e5dd7070Spatrick if (C.isCopyCapture()) {
1138e5dd7070Spatrick ClassType.removeLocalCVRQualifiers(Qualifiers::CVRMask);
1139e5dd7070Spatrick if (CurLSI->CallOperator->isConst())
1140e5dd7070Spatrick ClassType.addConst();
1141e5dd7070Spatrick return ASTCtx.getPointerType(ClassType);
1142e5dd7070Spatrick }
1143e5dd7070Spatrick }
1144e5dd7070Spatrick
1145*12c85518Srobert // 2) We've run out of ScopeInfos but check 1. if CurDC is a lambda (which
1146*12c85518Srobert // can happen during instantiation of its nested generic lambda call
1147*12c85518Srobert // operator); 2. if we're in a lambda scope (lambda body).
1148*12c85518Srobert if (CurLSI && isLambdaCallOperator(CurDC)) {
1149e5dd7070Spatrick assert(isGenericLambdaCallOperatorSpecialization(CurLSI->CallOperator) &&
1150e5dd7070Spatrick "While computing 'this' capture-type for a generic lambda, when we "
1151e5dd7070Spatrick "run out of enclosing LSI's, yet the enclosing DC is a "
1152e5dd7070Spatrick "lambda-call-operator we must be (i.e. Current LSI) in a generic "
1153e5dd7070Spatrick "lambda call oeprator");
1154e5dd7070Spatrick assert(CurDC == getLambdaAwareParentOfDeclContext(CurLSI->CallOperator));
1155e5dd7070Spatrick
1156e5dd7070Spatrick auto IsThisCaptured =
1157e5dd7070Spatrick [](CXXRecordDecl *Closure, bool &IsByCopy, bool &IsConst) {
1158e5dd7070Spatrick IsConst = false;
1159e5dd7070Spatrick IsByCopy = false;
1160e5dd7070Spatrick for (auto &&C : Closure->captures()) {
1161e5dd7070Spatrick if (C.capturesThis()) {
1162e5dd7070Spatrick if (C.getCaptureKind() == LCK_StarThis)
1163e5dd7070Spatrick IsByCopy = true;
1164e5dd7070Spatrick if (Closure->getLambdaCallOperator()->isConst())
1165e5dd7070Spatrick IsConst = true;
1166e5dd7070Spatrick return true;
1167e5dd7070Spatrick }
1168e5dd7070Spatrick }
1169e5dd7070Spatrick return false;
1170e5dd7070Spatrick };
1171e5dd7070Spatrick
1172e5dd7070Spatrick bool IsByCopyCapture = false;
1173e5dd7070Spatrick bool IsConstCapture = false;
1174e5dd7070Spatrick CXXRecordDecl *Closure = cast<CXXRecordDecl>(CurDC->getParent());
1175e5dd7070Spatrick while (Closure &&
1176e5dd7070Spatrick IsThisCaptured(Closure, IsByCopyCapture, IsConstCapture)) {
1177e5dd7070Spatrick if (IsByCopyCapture) {
1178e5dd7070Spatrick ClassType.removeLocalCVRQualifiers(Qualifiers::CVRMask);
1179e5dd7070Spatrick if (IsConstCapture)
1180e5dd7070Spatrick ClassType.addConst();
1181e5dd7070Spatrick return ASTCtx.getPointerType(ClassType);
1182e5dd7070Spatrick }
1183e5dd7070Spatrick Closure = isLambdaCallOperator(Closure->getParent())
1184e5dd7070Spatrick ? cast<CXXRecordDecl>(Closure->getParent()->getParent())
1185e5dd7070Spatrick : nullptr;
1186e5dd7070Spatrick }
1187e5dd7070Spatrick }
1188e5dd7070Spatrick return ASTCtx.getPointerType(ClassType);
1189e5dd7070Spatrick }
1190e5dd7070Spatrick
getCurrentThisType()1191e5dd7070Spatrick QualType Sema::getCurrentThisType() {
1192e5dd7070Spatrick DeclContext *DC = getFunctionLevelDeclContext();
1193e5dd7070Spatrick QualType ThisTy = CXXThisTypeOverride;
1194e5dd7070Spatrick
1195e5dd7070Spatrick if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC)) {
1196e5dd7070Spatrick if (method && method->isInstance())
1197e5dd7070Spatrick ThisTy = method->getThisType();
1198e5dd7070Spatrick }
1199e5dd7070Spatrick
1200e5dd7070Spatrick if (ThisTy.isNull() && isLambdaCallOperator(CurContext) &&
1201a9ac8606Spatrick inTemplateInstantiation() && isa<CXXRecordDecl>(DC)) {
1202e5dd7070Spatrick
1203e5dd7070Spatrick // This is a lambda call operator that is being instantiated as a default
1204e5dd7070Spatrick // initializer. DC must point to the enclosing class type, so we can recover
1205e5dd7070Spatrick // the 'this' type from it.
1206e5dd7070Spatrick QualType ClassTy = Context.getTypeDeclType(cast<CXXRecordDecl>(DC));
1207e5dd7070Spatrick // There are no cv-qualifiers for 'this' within default initializers,
1208e5dd7070Spatrick // per [expr.prim.general]p4.
1209e5dd7070Spatrick ThisTy = Context.getPointerType(ClassTy);
1210e5dd7070Spatrick }
1211e5dd7070Spatrick
1212e5dd7070Spatrick // If we are within a lambda's call operator, the cv-qualifiers of 'this'
1213e5dd7070Spatrick // might need to be adjusted if the lambda or any of its enclosing lambda's
1214e5dd7070Spatrick // captures '*this' by copy.
1215e5dd7070Spatrick if (!ThisTy.isNull() && isLambdaCallOperator(CurContext))
1216e5dd7070Spatrick return adjustCVQualifiersForCXXThisWithinLambda(FunctionScopes, ThisTy,
1217e5dd7070Spatrick CurContext, Context);
1218e5dd7070Spatrick return ThisTy;
1219e5dd7070Spatrick }
1220e5dd7070Spatrick
CXXThisScopeRAII(Sema & S,Decl * ContextDecl,Qualifiers CXXThisTypeQuals,bool Enabled)1221e5dd7070Spatrick Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S,
1222e5dd7070Spatrick Decl *ContextDecl,
1223e5dd7070Spatrick Qualifiers CXXThisTypeQuals,
1224e5dd7070Spatrick bool Enabled)
1225e5dd7070Spatrick : S(S), OldCXXThisTypeOverride(S.CXXThisTypeOverride), Enabled(false)
1226e5dd7070Spatrick {
1227e5dd7070Spatrick if (!Enabled || !ContextDecl)
1228e5dd7070Spatrick return;
1229e5dd7070Spatrick
1230e5dd7070Spatrick CXXRecordDecl *Record = nullptr;
1231e5dd7070Spatrick if (ClassTemplateDecl *Template = dyn_cast<ClassTemplateDecl>(ContextDecl))
1232e5dd7070Spatrick Record = Template->getTemplatedDecl();
1233e5dd7070Spatrick else
1234e5dd7070Spatrick Record = cast<CXXRecordDecl>(ContextDecl);
1235e5dd7070Spatrick
1236e5dd7070Spatrick QualType T = S.Context.getRecordType(Record);
1237e5dd7070Spatrick T = S.getASTContext().getQualifiedType(T, CXXThisTypeQuals);
1238e5dd7070Spatrick
1239e5dd7070Spatrick S.CXXThisTypeOverride = S.Context.getPointerType(T);
1240e5dd7070Spatrick
1241e5dd7070Spatrick this->Enabled = true;
1242e5dd7070Spatrick }
1243e5dd7070Spatrick
1244e5dd7070Spatrick
~CXXThisScopeRAII()1245e5dd7070Spatrick Sema::CXXThisScopeRAII::~CXXThisScopeRAII() {
1246e5dd7070Spatrick if (Enabled) {
1247e5dd7070Spatrick S.CXXThisTypeOverride = OldCXXThisTypeOverride;
1248e5dd7070Spatrick }
1249e5dd7070Spatrick }
1250e5dd7070Spatrick
buildLambdaThisCaptureFixit(Sema & Sema,LambdaScopeInfo * LSI)1251a9ac8606Spatrick static void buildLambdaThisCaptureFixit(Sema &Sema, LambdaScopeInfo *LSI) {
1252a9ac8606Spatrick SourceLocation DiagLoc = LSI->IntroducerRange.getEnd();
1253a9ac8606Spatrick assert(!LSI->isCXXThisCaptured());
1254a9ac8606Spatrick // [=, this] {}; // until C++20: Error: this when = is the default
1255a9ac8606Spatrick if (LSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval &&
1256a9ac8606Spatrick !Sema.getLangOpts().CPlusPlus20)
1257a9ac8606Spatrick return;
1258a9ac8606Spatrick Sema.Diag(DiagLoc, diag::note_lambda_this_capture_fixit)
1259a9ac8606Spatrick << FixItHint::CreateInsertion(
1260a9ac8606Spatrick DiagLoc, LSI->NumExplicitCaptures > 0 ? ", this" : "this");
1261a9ac8606Spatrick }
1262a9ac8606Spatrick
CheckCXXThisCapture(SourceLocation Loc,const bool Explicit,bool BuildAndDiagnose,const unsigned * const FunctionScopeIndexToStopAt,const bool ByCopy)1263e5dd7070Spatrick bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
1264e5dd7070Spatrick bool BuildAndDiagnose, const unsigned *const FunctionScopeIndexToStopAt,
1265e5dd7070Spatrick const bool ByCopy) {
1266e5dd7070Spatrick // We don't need to capture this in an unevaluated context.
1267e5dd7070Spatrick if (isUnevaluatedContext() && !Explicit)
1268e5dd7070Spatrick return true;
1269e5dd7070Spatrick
1270e5dd7070Spatrick assert((!ByCopy || Explicit) && "cannot implicitly capture *this by value");
1271e5dd7070Spatrick
1272e5dd7070Spatrick const int MaxFunctionScopesIndex = FunctionScopeIndexToStopAt
1273e5dd7070Spatrick ? *FunctionScopeIndexToStopAt
1274e5dd7070Spatrick : FunctionScopes.size() - 1;
1275e5dd7070Spatrick
1276e5dd7070Spatrick // Check that we can capture the *enclosing object* (referred to by '*this')
1277e5dd7070Spatrick // by the capturing-entity/closure (lambda/block/etc) at
1278e5dd7070Spatrick // MaxFunctionScopesIndex-deep on the FunctionScopes stack.
1279e5dd7070Spatrick
1280e5dd7070Spatrick // Note: The *enclosing object* can only be captured by-value by a
1281e5dd7070Spatrick // closure that is a lambda, using the explicit notation:
1282e5dd7070Spatrick // [*this] { ... }.
1283e5dd7070Spatrick // Every other capture of the *enclosing object* results in its by-reference
1284e5dd7070Spatrick // capture.
1285e5dd7070Spatrick
1286e5dd7070Spatrick // For a closure 'L' (at MaxFunctionScopesIndex in the FunctionScopes
1287e5dd7070Spatrick // stack), we can capture the *enclosing object* only if:
1288e5dd7070Spatrick // - 'L' has an explicit byref or byval capture of the *enclosing object*
1289e5dd7070Spatrick // - or, 'L' has an implicit capture.
1290e5dd7070Spatrick // AND
1291e5dd7070Spatrick // -- there is no enclosing closure
1292e5dd7070Spatrick // -- or, there is some enclosing closure 'E' that has already captured the
1293e5dd7070Spatrick // *enclosing object*, and every intervening closure (if any) between 'E'
1294e5dd7070Spatrick // and 'L' can implicitly capture the *enclosing object*.
1295e5dd7070Spatrick // -- or, every enclosing closure can implicitly capture the
1296e5dd7070Spatrick // *enclosing object*
1297e5dd7070Spatrick
1298e5dd7070Spatrick
1299e5dd7070Spatrick unsigned NumCapturingClosures = 0;
1300e5dd7070Spatrick for (int idx = MaxFunctionScopesIndex; idx >= 0; idx--) {
1301e5dd7070Spatrick if (CapturingScopeInfo *CSI =
1302e5dd7070Spatrick dyn_cast<CapturingScopeInfo>(FunctionScopes[idx])) {
1303e5dd7070Spatrick if (CSI->CXXThisCaptureIndex != 0) {
1304e5dd7070Spatrick // 'this' is already being captured; there isn't anything more to do.
1305e5dd7070Spatrick CSI->Captures[CSI->CXXThisCaptureIndex - 1].markUsed(BuildAndDiagnose);
1306e5dd7070Spatrick break;
1307e5dd7070Spatrick }
1308e5dd7070Spatrick LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI);
1309e5dd7070Spatrick if (LSI && isGenericLambdaCallOperatorSpecialization(LSI->CallOperator)) {
1310e5dd7070Spatrick // This context can't implicitly capture 'this'; fail out.
1311a9ac8606Spatrick if (BuildAndDiagnose) {
1312e5dd7070Spatrick Diag(Loc, diag::err_this_capture)
1313e5dd7070Spatrick << (Explicit && idx == MaxFunctionScopesIndex);
1314a9ac8606Spatrick if (!Explicit)
1315a9ac8606Spatrick buildLambdaThisCaptureFixit(*this, LSI);
1316a9ac8606Spatrick }
1317e5dd7070Spatrick return true;
1318e5dd7070Spatrick }
1319e5dd7070Spatrick if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref ||
1320e5dd7070Spatrick CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval ||
1321e5dd7070Spatrick CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block ||
1322e5dd7070Spatrick CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_CapturedRegion ||
1323e5dd7070Spatrick (Explicit && idx == MaxFunctionScopesIndex)) {
1324e5dd7070Spatrick // Regarding (Explicit && idx == MaxFunctionScopesIndex): only the first
1325e5dd7070Spatrick // iteration through can be an explicit capture, all enclosing closures,
1326e5dd7070Spatrick // if any, must perform implicit captures.
1327e5dd7070Spatrick
1328e5dd7070Spatrick // This closure can capture 'this'; continue looking upwards.
1329e5dd7070Spatrick NumCapturingClosures++;
1330e5dd7070Spatrick continue;
1331e5dd7070Spatrick }
1332e5dd7070Spatrick // This context can't implicitly capture 'this'; fail out.
1333e5dd7070Spatrick if (BuildAndDiagnose)
1334e5dd7070Spatrick Diag(Loc, diag::err_this_capture)
1335e5dd7070Spatrick << (Explicit && idx == MaxFunctionScopesIndex);
1336a9ac8606Spatrick
1337a9ac8606Spatrick if (!Explicit)
1338a9ac8606Spatrick buildLambdaThisCaptureFixit(*this, LSI);
1339e5dd7070Spatrick return true;
1340e5dd7070Spatrick }
1341e5dd7070Spatrick break;
1342e5dd7070Spatrick }
1343e5dd7070Spatrick if (!BuildAndDiagnose) return false;
1344e5dd7070Spatrick
1345e5dd7070Spatrick // If we got here, then the closure at MaxFunctionScopesIndex on the
1346e5dd7070Spatrick // FunctionScopes stack, can capture the *enclosing object*, so capture it
1347e5dd7070Spatrick // (including implicit by-reference captures in any enclosing closures).
1348e5dd7070Spatrick
1349e5dd7070Spatrick // In the loop below, respect the ByCopy flag only for the closure requesting
1350e5dd7070Spatrick // the capture (i.e. first iteration through the loop below). Ignore it for
1351e5dd7070Spatrick // all enclosing closure's up to NumCapturingClosures (since they must be
1352e5dd7070Spatrick // implicitly capturing the *enclosing object* by reference (see loop
1353e5dd7070Spatrick // above)).
1354e5dd7070Spatrick assert((!ByCopy ||
1355*12c85518Srobert isa<LambdaScopeInfo>(FunctionScopes[MaxFunctionScopesIndex])) &&
1356e5dd7070Spatrick "Only a lambda can capture the enclosing object (referred to by "
1357e5dd7070Spatrick "*this) by copy");
1358e5dd7070Spatrick QualType ThisTy = getCurrentThisType();
1359e5dd7070Spatrick for (int idx = MaxFunctionScopesIndex; NumCapturingClosures;
1360e5dd7070Spatrick --idx, --NumCapturingClosures) {
1361e5dd7070Spatrick CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
1362e5dd7070Spatrick
1363e5dd7070Spatrick // The type of the corresponding data member (not a 'this' pointer if 'by
1364e5dd7070Spatrick // copy').
1365e5dd7070Spatrick QualType CaptureType = ThisTy;
1366e5dd7070Spatrick if (ByCopy) {
1367e5dd7070Spatrick // If we are capturing the object referred to by '*this' by copy, ignore
1368e5dd7070Spatrick // any cv qualifiers inherited from the type of the member function for
1369e5dd7070Spatrick // the type of the closure-type's corresponding data member and any use
1370e5dd7070Spatrick // of 'this'.
1371e5dd7070Spatrick CaptureType = ThisTy->getPointeeType();
1372e5dd7070Spatrick CaptureType.removeLocalCVRQualifiers(Qualifiers::CVRMask);
1373e5dd7070Spatrick }
1374e5dd7070Spatrick
1375e5dd7070Spatrick bool isNested = NumCapturingClosures > 1;
1376e5dd7070Spatrick CSI->addThisCapture(isNested, Loc, CaptureType, ByCopy);
1377e5dd7070Spatrick }
1378e5dd7070Spatrick return false;
1379e5dd7070Spatrick }
1380e5dd7070Spatrick
ActOnCXXThis(SourceLocation Loc)1381e5dd7070Spatrick ExprResult Sema::ActOnCXXThis(SourceLocation Loc) {
1382e5dd7070Spatrick /// C++ 9.3.2: In the body of a non-static member function, the keyword this
1383e5dd7070Spatrick /// is a non-lvalue expression whose value is the address of the object for
1384e5dd7070Spatrick /// which the function is called.
1385e5dd7070Spatrick
1386e5dd7070Spatrick QualType ThisTy = getCurrentThisType();
1387e5dd7070Spatrick if (ThisTy.isNull())
1388e5dd7070Spatrick return Diag(Loc, diag::err_invalid_this_use);
1389e5dd7070Spatrick return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false);
1390e5dd7070Spatrick }
1391e5dd7070Spatrick
BuildCXXThisExpr(SourceLocation Loc,QualType Type,bool IsImplicit)1392e5dd7070Spatrick Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type,
1393e5dd7070Spatrick bool IsImplicit) {
1394*12c85518Srobert if (getLangOpts().HLSL && Type.getTypePtr()->isPointerType()) {
1395*12c85518Srobert auto *This = new (Context)
1396*12c85518Srobert CXXThisExpr(Loc, Type.getTypePtr()->getPointeeType(), IsImplicit);
1397*12c85518Srobert This->setValueKind(ExprValueKind::VK_LValue);
1398*12c85518Srobert MarkThisReferenced(This);
1399*12c85518Srobert return This;
1400*12c85518Srobert }
1401e5dd7070Spatrick auto *This = new (Context) CXXThisExpr(Loc, Type, IsImplicit);
1402e5dd7070Spatrick MarkThisReferenced(This);
1403e5dd7070Spatrick return This;
1404e5dd7070Spatrick }
1405e5dd7070Spatrick
MarkThisReferenced(CXXThisExpr * This)1406e5dd7070Spatrick void Sema::MarkThisReferenced(CXXThisExpr *This) {
1407e5dd7070Spatrick CheckCXXThisCapture(This->getExprLoc());
1408e5dd7070Spatrick }
1409e5dd7070Spatrick
isThisOutsideMemberFunctionBody(QualType BaseType)1410e5dd7070Spatrick bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) {
1411e5dd7070Spatrick // If we're outside the body of a member function, then we'll have a specified
1412e5dd7070Spatrick // type for 'this'.
1413e5dd7070Spatrick if (CXXThisTypeOverride.isNull())
1414e5dd7070Spatrick return false;
1415e5dd7070Spatrick
1416e5dd7070Spatrick // Determine whether we're looking into a class that's currently being
1417e5dd7070Spatrick // defined.
1418e5dd7070Spatrick CXXRecordDecl *Class = BaseType->getAsCXXRecordDecl();
1419e5dd7070Spatrick return Class && Class->isBeingDefined();
1420e5dd7070Spatrick }
1421e5dd7070Spatrick
1422e5dd7070Spatrick /// Parse construction of a specified type.
1423e5dd7070Spatrick /// Can be interpreted either as function-style casting ("int(x)")
1424e5dd7070Spatrick /// or class type construction ("ClassType(x,y,z)")
1425e5dd7070Spatrick /// or creation of a value-initialized type ("int()").
1426e5dd7070Spatrick ExprResult
ActOnCXXTypeConstructExpr(ParsedType TypeRep,SourceLocation LParenOrBraceLoc,MultiExprArg exprs,SourceLocation RParenOrBraceLoc,bool ListInitialization)1427e5dd7070Spatrick Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
1428e5dd7070Spatrick SourceLocation LParenOrBraceLoc,
1429e5dd7070Spatrick MultiExprArg exprs,
1430e5dd7070Spatrick SourceLocation RParenOrBraceLoc,
1431e5dd7070Spatrick bool ListInitialization) {
1432e5dd7070Spatrick if (!TypeRep)
1433e5dd7070Spatrick return ExprError();
1434e5dd7070Spatrick
1435e5dd7070Spatrick TypeSourceInfo *TInfo;
1436e5dd7070Spatrick QualType Ty = GetTypeFromParser(TypeRep, &TInfo);
1437e5dd7070Spatrick if (!TInfo)
1438e5dd7070Spatrick TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation());
1439e5dd7070Spatrick
1440e5dd7070Spatrick auto Result = BuildCXXTypeConstructExpr(TInfo, LParenOrBraceLoc, exprs,
1441e5dd7070Spatrick RParenOrBraceLoc, ListInitialization);
1442e5dd7070Spatrick // Avoid creating a non-type-dependent expression that contains typos.
1443e5dd7070Spatrick // Non-type-dependent expressions are liable to be discarded without
1444e5dd7070Spatrick // checking for embedded typos.
1445e5dd7070Spatrick if (!Result.isInvalid() && Result.get()->isInstantiationDependent() &&
1446e5dd7070Spatrick !Result.get()->isTypeDependent())
1447e5dd7070Spatrick Result = CorrectDelayedTyposInExpr(Result.get());
1448a9ac8606Spatrick else if (Result.isInvalid())
1449a9ac8606Spatrick Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(),
1450a9ac8606Spatrick RParenOrBraceLoc, exprs, Ty);
1451e5dd7070Spatrick return Result;
1452e5dd7070Spatrick }
1453e5dd7070Spatrick
1454e5dd7070Spatrick ExprResult
BuildCXXTypeConstructExpr(TypeSourceInfo * TInfo,SourceLocation LParenOrBraceLoc,MultiExprArg Exprs,SourceLocation RParenOrBraceLoc,bool ListInitialization)1455e5dd7070Spatrick Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
1456e5dd7070Spatrick SourceLocation LParenOrBraceLoc,
1457e5dd7070Spatrick MultiExprArg Exprs,
1458e5dd7070Spatrick SourceLocation RParenOrBraceLoc,
1459e5dd7070Spatrick bool ListInitialization) {
1460e5dd7070Spatrick QualType Ty = TInfo->getType();
1461e5dd7070Spatrick SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
1462e5dd7070Spatrick
1463*12c85518Srobert assert((!ListInitialization || Exprs.size() == 1) &&
1464*12c85518Srobert "List initialization must have exactly one expression.");
1465e5dd7070Spatrick SourceRange FullRange = SourceRange(TyBeginLoc, RParenOrBraceLoc);
1466e5dd7070Spatrick
1467*12c85518Srobert InitializedEntity Entity =
1468*12c85518Srobert InitializedEntity::InitializeTemporary(Context, TInfo);
1469e5dd7070Spatrick InitializationKind Kind =
1470e5dd7070Spatrick Exprs.size()
1471e5dd7070Spatrick ? ListInitialization
1472e5dd7070Spatrick ? InitializationKind::CreateDirectList(
1473e5dd7070Spatrick TyBeginLoc, LParenOrBraceLoc, RParenOrBraceLoc)
1474e5dd7070Spatrick : InitializationKind::CreateDirect(TyBeginLoc, LParenOrBraceLoc,
1475e5dd7070Spatrick RParenOrBraceLoc)
1476e5dd7070Spatrick : InitializationKind::CreateValue(TyBeginLoc, LParenOrBraceLoc,
1477e5dd7070Spatrick RParenOrBraceLoc);
1478e5dd7070Spatrick
1479e5dd7070Spatrick // C++1z [expr.type.conv]p1:
1480e5dd7070Spatrick // If the type is a placeholder for a deduced class type, [...perform class
1481e5dd7070Spatrick // template argument deduction...]
1482*12c85518Srobert // C++2b:
1483*12c85518Srobert // Otherwise, if the type contains a placeholder type, it is replaced by the
1484*12c85518Srobert // type determined by placeholder type deduction.
1485e5dd7070Spatrick DeducedType *Deduced = Ty->getContainedDeducedType();
1486*12c85518Srobert if (Deduced && !Deduced->isDeduced() &&
1487*12c85518Srobert isa<DeducedTemplateSpecializationType>(Deduced)) {
1488e5dd7070Spatrick Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity,
1489e5dd7070Spatrick Kind, Exprs);
1490e5dd7070Spatrick if (Ty.isNull())
1491e5dd7070Spatrick return ExprError();
1492e5dd7070Spatrick Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
1493*12c85518Srobert } else if (Deduced && !Deduced->isDeduced()) {
1494*12c85518Srobert MultiExprArg Inits = Exprs;
1495*12c85518Srobert if (ListInitialization) {
1496*12c85518Srobert auto *ILE = cast<InitListExpr>(Exprs[0]);
1497*12c85518Srobert Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits());
1498*12c85518Srobert }
1499*12c85518Srobert
1500*12c85518Srobert if (Inits.empty())
1501*12c85518Srobert return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_init_no_expression)
1502*12c85518Srobert << Ty << FullRange);
1503*12c85518Srobert if (Inits.size() > 1) {
1504*12c85518Srobert Expr *FirstBad = Inits[1];
1505*12c85518Srobert return ExprError(Diag(FirstBad->getBeginLoc(),
1506*12c85518Srobert diag::err_auto_expr_init_multiple_expressions)
1507*12c85518Srobert << Ty << FullRange);
1508*12c85518Srobert }
1509*12c85518Srobert if (getLangOpts().CPlusPlus2b) {
1510*12c85518Srobert if (Ty->getAs<AutoType>())
1511*12c85518Srobert Diag(TyBeginLoc, diag::warn_cxx20_compat_auto_expr) << FullRange;
1512*12c85518Srobert }
1513*12c85518Srobert Expr *Deduce = Inits[0];
1514*12c85518Srobert if (isa<InitListExpr>(Deduce))
1515*12c85518Srobert return ExprError(
1516*12c85518Srobert Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces)
1517*12c85518Srobert << ListInitialization << Ty << FullRange);
1518*12c85518Srobert QualType DeducedType;
1519*12c85518Srobert TemplateDeductionInfo Info(Deduce->getExprLoc());
1520*12c85518Srobert TemplateDeductionResult Result =
1521*12c85518Srobert DeduceAutoType(TInfo->getTypeLoc(), Deduce, DeducedType, Info);
1522*12c85518Srobert if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed)
1523*12c85518Srobert return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_deduction_failure)
1524*12c85518Srobert << Ty << Deduce->getType() << FullRange
1525*12c85518Srobert << Deduce->getSourceRange());
1526*12c85518Srobert if (DeducedType.isNull()) {
1527*12c85518Srobert assert(Result == TDK_AlreadyDiagnosed);
1528*12c85518Srobert return ExprError();
1529*12c85518Srobert }
1530*12c85518Srobert
1531*12c85518Srobert Ty = DeducedType;
1532*12c85518Srobert Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
1533e5dd7070Spatrick }
1534e5dd7070Spatrick
1535a9ac8606Spatrick if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
1536a9ac8606Spatrick // FIXME: CXXUnresolvedConstructExpr does not model list-initialization
1537a9ac8606Spatrick // directly. We work around this by dropping the locations of the braces.
1538a9ac8606Spatrick SourceRange Locs = ListInitialization
1539a9ac8606Spatrick ? SourceRange()
1540a9ac8606Spatrick : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
1541a9ac8606Spatrick return CXXUnresolvedConstructExpr::Create(Context, Ty.getNonReferenceType(),
1542a9ac8606Spatrick TInfo, Locs.getBegin(), Exprs,
1543a9ac8606Spatrick Locs.getEnd());
1544a9ac8606Spatrick }
1545a9ac8606Spatrick
1546e5dd7070Spatrick // C++ [expr.type.conv]p1:
1547e5dd7070Spatrick // If the expression list is a parenthesized single expression, the type
1548e5dd7070Spatrick // conversion expression is equivalent (in definedness, and if defined in
1549e5dd7070Spatrick // meaning) to the corresponding cast expression.
1550e5dd7070Spatrick if (Exprs.size() == 1 && !ListInitialization &&
1551e5dd7070Spatrick !isa<InitListExpr>(Exprs[0])) {
1552e5dd7070Spatrick Expr *Arg = Exprs[0];
1553e5dd7070Spatrick return BuildCXXFunctionalCastExpr(TInfo, Ty, LParenOrBraceLoc, Arg,
1554e5dd7070Spatrick RParenOrBraceLoc);
1555e5dd7070Spatrick }
1556e5dd7070Spatrick
1557e5dd7070Spatrick // For an expression of the form T(), T shall not be an array type.
1558e5dd7070Spatrick QualType ElemTy = Ty;
1559e5dd7070Spatrick if (Ty->isArrayType()) {
1560e5dd7070Spatrick if (!ListInitialization)
1561e5dd7070Spatrick return ExprError(Diag(TyBeginLoc, diag::err_value_init_for_array_type)
1562e5dd7070Spatrick << FullRange);
1563e5dd7070Spatrick ElemTy = Context.getBaseElementType(Ty);
1564e5dd7070Spatrick }
1565e5dd7070Spatrick
1566*12c85518Srobert // Only construct objects with object types.
1567*12c85518Srobert // The standard doesn't explicitly forbid function types here, but that's an
1568*12c85518Srobert // obvious oversight, as there's no way to dynamically construct a function
1569*12c85518Srobert // in general.
1570e5dd7070Spatrick if (Ty->isFunctionType())
1571e5dd7070Spatrick return ExprError(Diag(TyBeginLoc, diag::err_init_for_function_type)
1572e5dd7070Spatrick << Ty << FullRange);
1573e5dd7070Spatrick
1574e5dd7070Spatrick // C++17 [expr.type.conv]p2:
1575e5dd7070Spatrick // If the type is cv void and the initializer is (), the expression is a
1576e5dd7070Spatrick // prvalue of the specified type that performs no initialization.
1577e5dd7070Spatrick if (!Ty->isVoidType() &&
1578e5dd7070Spatrick RequireCompleteType(TyBeginLoc, ElemTy,
1579e5dd7070Spatrick diag::err_invalid_incomplete_type_use, FullRange))
1580e5dd7070Spatrick return ExprError();
1581e5dd7070Spatrick
1582e5dd7070Spatrick // Otherwise, the expression is a prvalue of the specified type whose
1583e5dd7070Spatrick // result object is direct-initialized (11.6) with the initializer.
1584e5dd7070Spatrick InitializationSequence InitSeq(*this, Entity, Kind, Exprs);
1585e5dd7070Spatrick ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Exprs);
1586e5dd7070Spatrick
1587e5dd7070Spatrick if (Result.isInvalid())
1588e5dd7070Spatrick return Result;
1589e5dd7070Spatrick
1590e5dd7070Spatrick Expr *Inner = Result.get();
1591e5dd7070Spatrick if (CXXBindTemporaryExpr *BTE = dyn_cast_or_null<CXXBindTemporaryExpr>(Inner))
1592e5dd7070Spatrick Inner = BTE->getSubExpr();
1593e5dd7070Spatrick if (!isa<CXXTemporaryObjectExpr>(Inner) &&
1594e5dd7070Spatrick !isa<CXXScalarValueInitExpr>(Inner)) {
1595e5dd7070Spatrick // If we created a CXXTemporaryObjectExpr, that node also represents the
1596e5dd7070Spatrick // functional cast. Otherwise, create an explicit cast to represent
1597e5dd7070Spatrick // the syntactic form of a functional-style cast that was used here.
1598e5dd7070Spatrick //
1599e5dd7070Spatrick // FIXME: Creating a CXXFunctionalCastExpr around a CXXConstructExpr
1600e5dd7070Spatrick // would give a more consistent AST representation than using a
1601e5dd7070Spatrick // CXXTemporaryObjectExpr. It's also weird that the functional cast
1602e5dd7070Spatrick // is sometimes handled by initialization and sometimes not.
1603e5dd7070Spatrick QualType ResultType = Result.get()->getType();
1604e5dd7070Spatrick SourceRange Locs = ListInitialization
1605e5dd7070Spatrick ? SourceRange()
1606e5dd7070Spatrick : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
1607e5dd7070Spatrick Result = CXXFunctionalCastExpr::Create(
1608e5dd7070Spatrick Context, ResultType, Expr::getValueKindForType(Ty), TInfo, CK_NoOp,
1609a9ac8606Spatrick Result.get(), /*Path=*/nullptr, CurFPFeatureOverrides(),
1610a9ac8606Spatrick Locs.getBegin(), Locs.getEnd());
1611e5dd7070Spatrick }
1612e5dd7070Spatrick
1613e5dd7070Spatrick return Result;
1614e5dd7070Spatrick }
1615e5dd7070Spatrick
isUsualDeallocationFunction(const CXXMethodDecl * Method)1616e5dd7070Spatrick bool Sema::isUsualDeallocationFunction(const CXXMethodDecl *Method) {
1617e5dd7070Spatrick // [CUDA] Ignore this function, if we can't call it.
1618*12c85518Srobert const FunctionDecl *Caller = getCurFunctionDecl(/*AllowLambda=*/true);
1619a9ac8606Spatrick if (getLangOpts().CUDA) {
1620a9ac8606Spatrick auto CallPreference = IdentifyCUDAPreference(Caller, Method);
1621a9ac8606Spatrick // If it's not callable at all, it's not the right function.
1622a9ac8606Spatrick if (CallPreference < CFP_WrongSide)
1623e5dd7070Spatrick return false;
1624a9ac8606Spatrick if (CallPreference == CFP_WrongSide) {
1625a9ac8606Spatrick // Maybe. We have to check if there are better alternatives.
1626a9ac8606Spatrick DeclContext::lookup_result R =
1627a9ac8606Spatrick Method->getDeclContext()->lookup(Method->getDeclName());
1628a9ac8606Spatrick for (const auto *D : R) {
1629a9ac8606Spatrick if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1630a9ac8606Spatrick if (IdentifyCUDAPreference(Caller, FD) > CFP_WrongSide)
1631a9ac8606Spatrick return false;
1632a9ac8606Spatrick }
1633a9ac8606Spatrick }
1634a9ac8606Spatrick // We've found no better variants.
1635a9ac8606Spatrick }
1636a9ac8606Spatrick }
1637e5dd7070Spatrick
1638e5dd7070Spatrick SmallVector<const FunctionDecl*, 4> PreventedBy;
1639e5dd7070Spatrick bool Result = Method->isUsualDeallocationFunction(PreventedBy);
1640e5dd7070Spatrick
1641e5dd7070Spatrick if (Result || !getLangOpts().CUDA || PreventedBy.empty())
1642e5dd7070Spatrick return Result;
1643e5dd7070Spatrick
1644e5dd7070Spatrick // In case of CUDA, return true if none of the 1-argument deallocator
1645e5dd7070Spatrick // functions are actually callable.
1646e5dd7070Spatrick return llvm::none_of(PreventedBy, [&](const FunctionDecl *FD) {
1647e5dd7070Spatrick assert(FD->getNumParams() == 1 &&
1648e5dd7070Spatrick "Only single-operand functions should be in PreventedBy");
1649e5dd7070Spatrick return IdentifyCUDAPreference(Caller, FD) >= CFP_HostDevice;
1650e5dd7070Spatrick });
1651e5dd7070Spatrick }
1652e5dd7070Spatrick
1653e5dd7070Spatrick /// Determine whether the given function is a non-placement
1654e5dd7070Spatrick /// deallocation function.
isNonPlacementDeallocationFunction(Sema & S,FunctionDecl * FD)1655e5dd7070Spatrick static bool isNonPlacementDeallocationFunction(Sema &S, FunctionDecl *FD) {
1656e5dd7070Spatrick if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD))
1657e5dd7070Spatrick return S.isUsualDeallocationFunction(Method);
1658e5dd7070Spatrick
1659e5dd7070Spatrick if (FD->getOverloadedOperator() != OO_Delete &&
1660e5dd7070Spatrick FD->getOverloadedOperator() != OO_Array_Delete)
1661e5dd7070Spatrick return false;
1662e5dd7070Spatrick
1663e5dd7070Spatrick unsigned UsualParams = 1;
1664e5dd7070Spatrick
1665e5dd7070Spatrick if (S.getLangOpts().SizedDeallocation && UsualParams < FD->getNumParams() &&
1666e5dd7070Spatrick S.Context.hasSameUnqualifiedType(
1667e5dd7070Spatrick FD->getParamDecl(UsualParams)->getType(),
1668e5dd7070Spatrick S.Context.getSizeType()))
1669e5dd7070Spatrick ++UsualParams;
1670e5dd7070Spatrick
1671e5dd7070Spatrick if (S.getLangOpts().AlignedAllocation && UsualParams < FD->getNumParams() &&
1672e5dd7070Spatrick S.Context.hasSameUnqualifiedType(
1673e5dd7070Spatrick FD->getParamDecl(UsualParams)->getType(),
1674e5dd7070Spatrick S.Context.getTypeDeclType(S.getStdAlignValT())))
1675e5dd7070Spatrick ++UsualParams;
1676e5dd7070Spatrick
1677e5dd7070Spatrick return UsualParams == FD->getNumParams();
1678e5dd7070Spatrick }
1679e5dd7070Spatrick
1680e5dd7070Spatrick namespace {
1681e5dd7070Spatrick struct UsualDeallocFnInfo {
UsualDeallocFnInfo__anonf8dedf7e0a11::UsualDeallocFnInfo1682e5dd7070Spatrick UsualDeallocFnInfo() : Found(), FD(nullptr) {}
UsualDeallocFnInfo__anonf8dedf7e0a11::UsualDeallocFnInfo1683e5dd7070Spatrick UsualDeallocFnInfo(Sema &S, DeclAccessPair Found)
1684e5dd7070Spatrick : Found(Found), FD(dyn_cast<FunctionDecl>(Found->getUnderlyingDecl())),
1685e5dd7070Spatrick Destroying(false), HasSizeT(false), HasAlignValT(false),
1686e5dd7070Spatrick CUDAPref(Sema::CFP_Native) {
1687e5dd7070Spatrick // A function template declaration is never a usual deallocation function.
1688e5dd7070Spatrick if (!FD)
1689e5dd7070Spatrick return;
1690e5dd7070Spatrick unsigned NumBaseParams = 1;
1691e5dd7070Spatrick if (FD->isDestroyingOperatorDelete()) {
1692e5dd7070Spatrick Destroying = true;
1693e5dd7070Spatrick ++NumBaseParams;
1694e5dd7070Spatrick }
1695e5dd7070Spatrick
1696e5dd7070Spatrick if (NumBaseParams < FD->getNumParams() &&
1697e5dd7070Spatrick S.Context.hasSameUnqualifiedType(
1698e5dd7070Spatrick FD->getParamDecl(NumBaseParams)->getType(),
1699e5dd7070Spatrick S.Context.getSizeType())) {
1700e5dd7070Spatrick ++NumBaseParams;
1701e5dd7070Spatrick HasSizeT = true;
1702e5dd7070Spatrick }
1703e5dd7070Spatrick
1704e5dd7070Spatrick if (NumBaseParams < FD->getNumParams() &&
1705e5dd7070Spatrick FD->getParamDecl(NumBaseParams)->getType()->isAlignValT()) {
1706e5dd7070Spatrick ++NumBaseParams;
1707e5dd7070Spatrick HasAlignValT = true;
1708e5dd7070Spatrick }
1709e5dd7070Spatrick
1710e5dd7070Spatrick // In CUDA, determine how much we'd like / dislike to call this.
1711e5dd7070Spatrick if (S.getLangOpts().CUDA)
1712*12c85518Srobert if (auto *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true))
1713e5dd7070Spatrick CUDAPref = S.IdentifyCUDAPreference(Caller, FD);
1714e5dd7070Spatrick }
1715e5dd7070Spatrick
operator bool__anonf8dedf7e0a11::UsualDeallocFnInfo1716e5dd7070Spatrick explicit operator bool() const { return FD; }
1717e5dd7070Spatrick
isBetterThan__anonf8dedf7e0a11::UsualDeallocFnInfo1718e5dd7070Spatrick bool isBetterThan(const UsualDeallocFnInfo &Other, bool WantSize,
1719e5dd7070Spatrick bool WantAlign) const {
1720e5dd7070Spatrick // C++ P0722:
1721e5dd7070Spatrick // A destroying operator delete is preferred over a non-destroying
1722e5dd7070Spatrick // operator delete.
1723e5dd7070Spatrick if (Destroying != Other.Destroying)
1724e5dd7070Spatrick return Destroying;
1725e5dd7070Spatrick
1726e5dd7070Spatrick // C++17 [expr.delete]p10:
1727e5dd7070Spatrick // If the type has new-extended alignment, a function with a parameter
1728e5dd7070Spatrick // of type std::align_val_t is preferred; otherwise a function without
1729e5dd7070Spatrick // such a parameter is preferred
1730e5dd7070Spatrick if (HasAlignValT != Other.HasAlignValT)
1731e5dd7070Spatrick return HasAlignValT == WantAlign;
1732e5dd7070Spatrick
1733e5dd7070Spatrick if (HasSizeT != Other.HasSizeT)
1734e5dd7070Spatrick return HasSizeT == WantSize;
1735e5dd7070Spatrick
1736e5dd7070Spatrick // Use CUDA call preference as a tiebreaker.
1737e5dd7070Spatrick return CUDAPref > Other.CUDAPref;
1738e5dd7070Spatrick }
1739e5dd7070Spatrick
1740e5dd7070Spatrick DeclAccessPair Found;
1741e5dd7070Spatrick FunctionDecl *FD;
1742e5dd7070Spatrick bool Destroying, HasSizeT, HasAlignValT;
1743e5dd7070Spatrick Sema::CUDAFunctionPreference CUDAPref;
1744e5dd7070Spatrick };
1745e5dd7070Spatrick }
1746e5dd7070Spatrick
1747e5dd7070Spatrick /// Determine whether a type has new-extended alignment. This may be called when
1748e5dd7070Spatrick /// the type is incomplete (for a delete-expression with an incomplete pointee
1749e5dd7070Spatrick /// type), in which case it will conservatively return false if the alignment is
1750e5dd7070Spatrick /// not known.
hasNewExtendedAlignment(Sema & S,QualType AllocType)1751e5dd7070Spatrick static bool hasNewExtendedAlignment(Sema &S, QualType AllocType) {
1752e5dd7070Spatrick return S.getLangOpts().AlignedAllocation &&
1753e5dd7070Spatrick S.getASTContext().getTypeAlignIfKnown(AllocType) >
1754e5dd7070Spatrick S.getASTContext().getTargetInfo().getNewAlign();
1755e5dd7070Spatrick }
1756e5dd7070Spatrick
1757e5dd7070Spatrick /// Select the correct "usual" deallocation function to use from a selection of
1758e5dd7070Spatrick /// deallocation functions (either global or class-scope).
resolveDeallocationOverload(Sema & S,LookupResult & R,bool WantSize,bool WantAlign,llvm::SmallVectorImpl<UsualDeallocFnInfo> * BestFns=nullptr)1759e5dd7070Spatrick static UsualDeallocFnInfo resolveDeallocationOverload(
1760e5dd7070Spatrick Sema &S, LookupResult &R, bool WantSize, bool WantAlign,
1761e5dd7070Spatrick llvm::SmallVectorImpl<UsualDeallocFnInfo> *BestFns = nullptr) {
1762e5dd7070Spatrick UsualDeallocFnInfo Best;
1763e5dd7070Spatrick
1764e5dd7070Spatrick for (auto I = R.begin(), E = R.end(); I != E; ++I) {
1765e5dd7070Spatrick UsualDeallocFnInfo Info(S, I.getPair());
1766e5dd7070Spatrick if (!Info || !isNonPlacementDeallocationFunction(S, Info.FD) ||
1767e5dd7070Spatrick Info.CUDAPref == Sema::CFP_Never)
1768e5dd7070Spatrick continue;
1769e5dd7070Spatrick
1770e5dd7070Spatrick if (!Best) {
1771e5dd7070Spatrick Best = Info;
1772e5dd7070Spatrick if (BestFns)
1773e5dd7070Spatrick BestFns->push_back(Info);
1774e5dd7070Spatrick continue;
1775e5dd7070Spatrick }
1776e5dd7070Spatrick
1777e5dd7070Spatrick if (Best.isBetterThan(Info, WantSize, WantAlign))
1778e5dd7070Spatrick continue;
1779e5dd7070Spatrick
1780e5dd7070Spatrick // If more than one preferred function is found, all non-preferred
1781e5dd7070Spatrick // functions are eliminated from further consideration.
1782e5dd7070Spatrick if (BestFns && Info.isBetterThan(Best, WantSize, WantAlign))
1783e5dd7070Spatrick BestFns->clear();
1784e5dd7070Spatrick
1785e5dd7070Spatrick Best = Info;
1786e5dd7070Spatrick if (BestFns)
1787e5dd7070Spatrick BestFns->push_back(Info);
1788e5dd7070Spatrick }
1789e5dd7070Spatrick
1790e5dd7070Spatrick return Best;
1791e5dd7070Spatrick }
1792e5dd7070Spatrick
1793e5dd7070Spatrick /// Determine whether a given type is a class for which 'delete[]' would call
1794e5dd7070Spatrick /// a member 'operator delete[]' with a 'size_t' parameter. This implies that
1795e5dd7070Spatrick /// we need to store the array size (even if the type is
1796e5dd7070Spatrick /// trivially-destructible).
doesUsualArrayDeleteWantSize(Sema & S,SourceLocation loc,QualType allocType)1797e5dd7070Spatrick static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc,
1798e5dd7070Spatrick QualType allocType) {
1799e5dd7070Spatrick const RecordType *record =
1800e5dd7070Spatrick allocType->getBaseElementTypeUnsafe()->getAs<RecordType>();
1801e5dd7070Spatrick if (!record) return false;
1802e5dd7070Spatrick
1803e5dd7070Spatrick // Try to find an operator delete[] in class scope.
1804e5dd7070Spatrick
1805e5dd7070Spatrick DeclarationName deleteName =
1806e5dd7070Spatrick S.Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
1807e5dd7070Spatrick LookupResult ops(S, deleteName, loc, Sema::LookupOrdinaryName);
1808e5dd7070Spatrick S.LookupQualifiedName(ops, record->getDecl());
1809e5dd7070Spatrick
1810e5dd7070Spatrick // We're just doing this for information.
1811e5dd7070Spatrick ops.suppressDiagnostics();
1812e5dd7070Spatrick
1813e5dd7070Spatrick // Very likely: there's no operator delete[].
1814e5dd7070Spatrick if (ops.empty()) return false;
1815e5dd7070Spatrick
1816e5dd7070Spatrick // If it's ambiguous, it should be illegal to call operator delete[]
1817e5dd7070Spatrick // on this thing, so it doesn't matter if we allocate extra space or not.
1818e5dd7070Spatrick if (ops.isAmbiguous()) return false;
1819e5dd7070Spatrick
1820e5dd7070Spatrick // C++17 [expr.delete]p10:
1821e5dd7070Spatrick // If the deallocation functions have class scope, the one without a
1822e5dd7070Spatrick // parameter of type std::size_t is selected.
1823e5dd7070Spatrick auto Best = resolveDeallocationOverload(
1824e5dd7070Spatrick S, ops, /*WantSize*/false,
1825e5dd7070Spatrick /*WantAlign*/hasNewExtendedAlignment(S, allocType));
1826e5dd7070Spatrick return Best && Best.HasSizeT;
1827e5dd7070Spatrick }
1828e5dd7070Spatrick
1829e5dd7070Spatrick /// Parsed a C++ 'new' expression (C++ 5.3.4).
1830e5dd7070Spatrick ///
1831e5dd7070Spatrick /// E.g.:
1832e5dd7070Spatrick /// @code new (memory) int[size][4] @endcode
1833e5dd7070Spatrick /// or
1834e5dd7070Spatrick /// @code ::new Foo(23, "hello") @endcode
1835e5dd7070Spatrick ///
1836e5dd7070Spatrick /// \param StartLoc The first location of the expression.
1837e5dd7070Spatrick /// \param UseGlobal True if 'new' was prefixed with '::'.
1838e5dd7070Spatrick /// \param PlacementLParen Opening paren of the placement arguments.
1839e5dd7070Spatrick /// \param PlacementArgs Placement new arguments.
1840e5dd7070Spatrick /// \param PlacementRParen Closing paren of the placement arguments.
1841e5dd7070Spatrick /// \param TypeIdParens If the type is in parens, the source range.
1842e5dd7070Spatrick /// \param D The type to be allocated, as well as array dimensions.
1843e5dd7070Spatrick /// \param Initializer The initializing expression or initializer-list, or null
1844e5dd7070Spatrick /// if there is none.
1845e5dd7070Spatrick ExprResult
ActOnCXXNew(SourceLocation StartLoc,bool UseGlobal,SourceLocation PlacementLParen,MultiExprArg PlacementArgs,SourceLocation PlacementRParen,SourceRange TypeIdParens,Declarator & D,Expr * Initializer)1846e5dd7070Spatrick Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
1847e5dd7070Spatrick SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
1848e5dd7070Spatrick SourceLocation PlacementRParen, SourceRange TypeIdParens,
1849e5dd7070Spatrick Declarator &D, Expr *Initializer) {
1850*12c85518Srobert std::optional<Expr *> ArraySize;
1851e5dd7070Spatrick // If the specified type is an array, unwrap it and save the expression.
1852e5dd7070Spatrick if (D.getNumTypeObjects() > 0 &&
1853e5dd7070Spatrick D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
1854e5dd7070Spatrick DeclaratorChunk &Chunk = D.getTypeObject(0);
1855e5dd7070Spatrick if (D.getDeclSpec().hasAutoTypeSpec())
1856e5dd7070Spatrick return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto)
1857e5dd7070Spatrick << D.getSourceRange());
1858e5dd7070Spatrick if (Chunk.Arr.hasStatic)
1859e5dd7070Spatrick return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new)
1860e5dd7070Spatrick << D.getSourceRange());
1861e5dd7070Spatrick if (!Chunk.Arr.NumElts && !Initializer)
1862e5dd7070Spatrick return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size)
1863e5dd7070Spatrick << D.getSourceRange());
1864e5dd7070Spatrick
1865e5dd7070Spatrick ArraySize = static_cast<Expr*>(Chunk.Arr.NumElts);
1866e5dd7070Spatrick D.DropFirstTypeObject();
1867e5dd7070Spatrick }
1868e5dd7070Spatrick
1869e5dd7070Spatrick // Every dimension shall be of constant size.
1870e5dd7070Spatrick if (ArraySize) {
1871e5dd7070Spatrick for (unsigned I = 0, N = D.getNumTypeObjects(); I < N; ++I) {
1872e5dd7070Spatrick if (D.getTypeObject(I).Kind != DeclaratorChunk::Array)
1873e5dd7070Spatrick break;
1874e5dd7070Spatrick
1875e5dd7070Spatrick DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr;
1876e5dd7070Spatrick if (Expr *NumElts = (Expr *)Array.NumElts) {
1877e5dd7070Spatrick if (!NumElts->isTypeDependent() && !NumElts->isValueDependent()) {
1878a9ac8606Spatrick // FIXME: GCC permits constant folding here. We should either do so consistently
1879a9ac8606Spatrick // or not do so at all, rather than changing behavior in C++14 onwards.
1880e5dd7070Spatrick if (getLangOpts().CPlusPlus14) {
1881e5dd7070Spatrick // C++1y [expr.new]p6: Every constant-expression in a noptr-new-declarator
1882e5dd7070Spatrick // shall be a converted constant expression (5.19) of type std::size_t
1883e5dd7070Spatrick // and shall evaluate to a strictly positive value.
1884a9ac8606Spatrick llvm::APSInt Value(Context.getIntWidth(Context.getSizeType()));
1885e5dd7070Spatrick Array.NumElts
1886e5dd7070Spatrick = CheckConvertedConstantExpression(NumElts, Context.getSizeType(), Value,
1887a9ac8606Spatrick CCEK_ArrayBound)
1888e5dd7070Spatrick .get();
1889e5dd7070Spatrick } else {
1890a9ac8606Spatrick Array.NumElts =
1891a9ac8606Spatrick VerifyIntegerConstantExpression(
1892a9ac8606Spatrick NumElts, nullptr, diag::err_new_array_nonconst, AllowFold)
1893e5dd7070Spatrick .get();
1894e5dd7070Spatrick }
1895e5dd7070Spatrick if (!Array.NumElts)
1896e5dd7070Spatrick return ExprError();
1897e5dd7070Spatrick }
1898e5dd7070Spatrick }
1899e5dd7070Spatrick }
1900e5dd7070Spatrick }
1901e5dd7070Spatrick
1902e5dd7070Spatrick TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/nullptr);
1903e5dd7070Spatrick QualType AllocType = TInfo->getType();
1904e5dd7070Spatrick if (D.isInvalidType())
1905e5dd7070Spatrick return ExprError();
1906e5dd7070Spatrick
1907e5dd7070Spatrick SourceRange DirectInitRange;
1908e5dd7070Spatrick if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer))
1909e5dd7070Spatrick DirectInitRange = List->getSourceRange();
1910e5dd7070Spatrick
1911e5dd7070Spatrick return BuildCXXNew(SourceRange(StartLoc, D.getEndLoc()), UseGlobal,
1912e5dd7070Spatrick PlacementLParen, PlacementArgs, PlacementRParen,
1913e5dd7070Spatrick TypeIdParens, AllocType, TInfo, ArraySize, DirectInitRange,
1914e5dd7070Spatrick Initializer);
1915e5dd7070Spatrick }
1916e5dd7070Spatrick
isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,Expr * Init)1917e5dd7070Spatrick static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,
1918e5dd7070Spatrick Expr *Init) {
1919e5dd7070Spatrick if (!Init)
1920e5dd7070Spatrick return true;
1921e5dd7070Spatrick if (ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init))
1922e5dd7070Spatrick return PLE->getNumExprs() == 0;
1923e5dd7070Spatrick if (isa<ImplicitValueInitExpr>(Init))
1924e5dd7070Spatrick return true;
1925e5dd7070Spatrick else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init))
1926e5dd7070Spatrick return !CCE->isListInitialization() &&
1927e5dd7070Spatrick CCE->getConstructor()->isDefaultConstructor();
1928e5dd7070Spatrick else if (Style == CXXNewExpr::ListInit) {
1929e5dd7070Spatrick assert(isa<InitListExpr>(Init) &&
1930e5dd7070Spatrick "Shouldn't create list CXXConstructExprs for arrays.");
1931e5dd7070Spatrick return true;
1932e5dd7070Spatrick }
1933e5dd7070Spatrick return false;
1934e5dd7070Spatrick }
1935e5dd7070Spatrick
1936e5dd7070Spatrick bool
isUnavailableAlignedAllocationFunction(const FunctionDecl & FD) const1937e5dd7070Spatrick Sema::isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const {
1938e5dd7070Spatrick if (!getLangOpts().AlignedAllocationUnavailable)
1939e5dd7070Spatrick return false;
1940e5dd7070Spatrick if (FD.isDefined())
1941e5dd7070Spatrick return false;
1942*12c85518Srobert std::optional<unsigned> AlignmentParam;
1943ec727ea7Spatrick if (FD.isReplaceableGlobalAllocationFunction(&AlignmentParam) &&
1944*12c85518Srobert AlignmentParam)
1945e5dd7070Spatrick return true;
1946e5dd7070Spatrick return false;
1947e5dd7070Spatrick }
1948e5dd7070Spatrick
1949e5dd7070Spatrick // Emit a diagnostic if an aligned allocation/deallocation function that is not
1950e5dd7070Spatrick // implemented in the standard library is selected.
diagnoseUnavailableAlignedAllocation(const FunctionDecl & FD,SourceLocation Loc)1951e5dd7070Spatrick void Sema::diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
1952e5dd7070Spatrick SourceLocation Loc) {
1953e5dd7070Spatrick if (isUnavailableAlignedAllocationFunction(FD)) {
1954e5dd7070Spatrick const llvm::Triple &T = getASTContext().getTargetInfo().getTriple();
1955e5dd7070Spatrick StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling(
1956e5dd7070Spatrick getASTContext().getTargetInfo().getPlatformName());
1957a9ac8606Spatrick VersionTuple OSVersion = alignedAllocMinVersion(T.getOS());
1958e5dd7070Spatrick
1959e5dd7070Spatrick OverloadedOperatorKind Kind = FD.getDeclName().getCXXOverloadedOperator();
1960e5dd7070Spatrick bool IsDelete = Kind == OO_Delete || Kind == OO_Array_Delete;
1961e5dd7070Spatrick Diag(Loc, diag::err_aligned_allocation_unavailable)
1962e5dd7070Spatrick << IsDelete << FD.getType().getAsString() << OSName
1963a9ac8606Spatrick << OSVersion.getAsString() << OSVersion.empty();
1964e5dd7070Spatrick Diag(Loc, diag::note_silence_aligned_allocation_unavailable);
1965e5dd7070Spatrick }
1966e5dd7070Spatrick }
1967e5dd7070Spatrick
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)1968*12c85518Srobert ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
1969e5dd7070Spatrick SourceLocation PlacementLParen,
1970e5dd7070Spatrick MultiExprArg PlacementArgs,
1971e5dd7070Spatrick SourceLocation PlacementRParen,
1972*12c85518Srobert SourceRange TypeIdParens, QualType AllocType,
1973e5dd7070Spatrick TypeSourceInfo *AllocTypeInfo,
1974*12c85518Srobert std::optional<Expr *> ArraySize,
1975*12c85518Srobert SourceRange DirectInitRange, Expr *Initializer) {
1976e5dd7070Spatrick SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
1977e5dd7070Spatrick SourceLocation StartLoc = Range.getBegin();
1978e5dd7070Spatrick
1979e5dd7070Spatrick CXXNewExpr::InitializationStyle initStyle;
1980e5dd7070Spatrick if (DirectInitRange.isValid()) {
1981e5dd7070Spatrick assert(Initializer && "Have parens but no initializer.");
1982e5dd7070Spatrick initStyle = CXXNewExpr::CallInit;
1983e5dd7070Spatrick } else if (Initializer && isa<InitListExpr>(Initializer))
1984e5dd7070Spatrick initStyle = CXXNewExpr::ListInit;
1985e5dd7070Spatrick else {
1986e5dd7070Spatrick assert((!Initializer || isa<ImplicitValueInitExpr>(Initializer) ||
1987e5dd7070Spatrick isa<CXXConstructExpr>(Initializer)) &&
1988e5dd7070Spatrick "Initializer expression that cannot have been implicitly created.");
1989e5dd7070Spatrick initStyle = CXXNewExpr::NoInit;
1990e5dd7070Spatrick }
1991e5dd7070Spatrick
1992*12c85518Srobert MultiExprArg Exprs(&Initializer, Initializer ? 1 : 0);
1993e5dd7070Spatrick if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer)) {
1994e5dd7070Spatrick assert(initStyle == CXXNewExpr::CallInit && "paren init for non-call init");
1995*12c85518Srobert Exprs = MultiExprArg(List->getExprs(), List->getNumExprs());
1996e5dd7070Spatrick }
1997e5dd7070Spatrick
1998e5dd7070Spatrick // C++11 [expr.new]p15:
1999e5dd7070Spatrick // A new-expression that creates an object of type T initializes that
2000e5dd7070Spatrick // object as follows:
2001e5dd7070Spatrick InitializationKind Kind
2002e5dd7070Spatrick // - If the new-initializer is omitted, the object is default-
2003e5dd7070Spatrick // initialized (8.5); if no initialization is performed,
2004e5dd7070Spatrick // the object has indeterminate value
2005e5dd7070Spatrick = initStyle == CXXNewExpr::NoInit
2006e5dd7070Spatrick ? InitializationKind::CreateDefault(TypeRange.getBegin())
2007e5dd7070Spatrick // - Otherwise, the new-initializer is interpreted according to
2008e5dd7070Spatrick // the
2009e5dd7070Spatrick // initialization rules of 8.5 for direct-initialization.
2010e5dd7070Spatrick : initStyle == CXXNewExpr::ListInit
2011e5dd7070Spatrick ? InitializationKind::CreateDirectList(
2012e5dd7070Spatrick TypeRange.getBegin(), Initializer->getBeginLoc(),
2013e5dd7070Spatrick Initializer->getEndLoc())
2014e5dd7070Spatrick : InitializationKind::CreateDirect(TypeRange.getBegin(),
2015e5dd7070Spatrick DirectInitRange.getBegin(),
2016e5dd7070Spatrick DirectInitRange.getEnd());
2017e5dd7070Spatrick
2018e5dd7070Spatrick // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
2019e5dd7070Spatrick auto *Deduced = AllocType->getContainedDeducedType();
2020*12c85518Srobert if (Deduced && !Deduced->isDeduced() &&
2021*12c85518Srobert isa<DeducedTemplateSpecializationType>(Deduced)) {
2022e5dd7070Spatrick if (ArraySize)
2023e5dd7070Spatrick return ExprError(
2024*12c85518Srobert Diag(*ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(),
2025e5dd7070Spatrick diag::err_deduced_class_template_compound_type)
2026e5dd7070Spatrick << /*array*/ 2
2027*12c85518Srobert << (*ArraySize ? (*ArraySize)->getSourceRange() : TypeRange));
2028e5dd7070Spatrick
2029e5dd7070Spatrick InitializedEntity Entity
2030e5dd7070Spatrick = InitializedEntity::InitializeNew(StartLoc, AllocType);
2031e5dd7070Spatrick AllocType = DeduceTemplateSpecializationFromInitializer(
2032*12c85518Srobert AllocTypeInfo, Entity, Kind, Exprs);
2033e5dd7070Spatrick if (AllocType.isNull())
2034e5dd7070Spatrick return ExprError();
2035*12c85518Srobert } else if (Deduced && !Deduced->isDeduced()) {
2036*12c85518Srobert MultiExprArg Inits = Exprs;
2037e5dd7070Spatrick bool Braced = (initStyle == CXXNewExpr::ListInit);
2038*12c85518Srobert if (Braced) {
2039*12c85518Srobert auto *ILE = cast<InitListExpr>(Exprs[0]);
2040*12c85518Srobert Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits());
2041e5dd7070Spatrick }
2042e5dd7070Spatrick
2043*12c85518Srobert if (initStyle == CXXNewExpr::NoInit || Inits.empty())
2044e5dd7070Spatrick return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
2045e5dd7070Spatrick << AllocType << TypeRange);
2046*12c85518Srobert if (Inits.size() > 1) {
2047e5dd7070Spatrick Expr *FirstBad = Inits[1];
2048e5dd7070Spatrick return ExprError(Diag(FirstBad->getBeginLoc(),
2049e5dd7070Spatrick diag::err_auto_new_ctor_multiple_expressions)
2050e5dd7070Spatrick << AllocType << TypeRange);
2051e5dd7070Spatrick }
2052e5dd7070Spatrick if (Braced && !getLangOpts().CPlusPlus17)
2053e5dd7070Spatrick Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init)
2054e5dd7070Spatrick << AllocType << TypeRange;
2055e5dd7070Spatrick Expr *Deduce = Inits[0];
2056*12c85518Srobert if (isa<InitListExpr>(Deduce))
2057*12c85518Srobert return ExprError(
2058*12c85518Srobert Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces)
2059*12c85518Srobert << Braced << AllocType << TypeRange);
2060e5dd7070Spatrick QualType DeducedType;
2061*12c85518Srobert TemplateDeductionInfo Info(Deduce->getExprLoc());
2062*12c85518Srobert TemplateDeductionResult Result =
2063*12c85518Srobert DeduceAutoType(AllocTypeInfo->getTypeLoc(), Deduce, DeducedType, Info);
2064*12c85518Srobert if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed)
2065e5dd7070Spatrick return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
2066*12c85518Srobert << AllocType << Deduce->getType() << TypeRange
2067*12c85518Srobert << Deduce->getSourceRange());
2068*12c85518Srobert if (DeducedType.isNull()) {
2069*12c85518Srobert assert(Result == TDK_AlreadyDiagnosed);
2070e5dd7070Spatrick return ExprError();
2071*12c85518Srobert }
2072e5dd7070Spatrick AllocType = DeducedType;
2073e5dd7070Spatrick }
2074e5dd7070Spatrick
2075e5dd7070Spatrick // Per C++0x [expr.new]p5, the type being constructed may be a
2076e5dd7070Spatrick // typedef of an array type.
2077e5dd7070Spatrick if (!ArraySize) {
2078e5dd7070Spatrick if (const ConstantArrayType *Array
2079e5dd7070Spatrick = Context.getAsConstantArrayType(AllocType)) {
2080e5dd7070Spatrick ArraySize = IntegerLiteral::Create(Context, Array->getSize(),
2081e5dd7070Spatrick Context.getSizeType(),
2082e5dd7070Spatrick TypeRange.getEnd());
2083e5dd7070Spatrick AllocType = Array->getElementType();
2084e5dd7070Spatrick }
2085e5dd7070Spatrick }
2086e5dd7070Spatrick
2087e5dd7070Spatrick if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange))
2088e5dd7070Spatrick return ExprError();
2089e5dd7070Spatrick
2090*12c85518Srobert if (ArraySize && !checkArrayElementAlignment(AllocType, TypeRange.getBegin()))
2091*12c85518Srobert return ExprError();
2092*12c85518Srobert
2093e5dd7070Spatrick // In ARC, infer 'retaining' for the allocated
2094e5dd7070Spatrick if (getLangOpts().ObjCAutoRefCount &&
2095e5dd7070Spatrick AllocType.getObjCLifetime() == Qualifiers::OCL_None &&
2096e5dd7070Spatrick AllocType->isObjCLifetimeType()) {
2097e5dd7070Spatrick AllocType = Context.getLifetimeQualifiedType(AllocType,
2098e5dd7070Spatrick AllocType->getObjCARCImplicitLifetime());
2099e5dd7070Spatrick }
2100e5dd7070Spatrick
2101e5dd7070Spatrick QualType ResultType = Context.getPointerType(AllocType);
2102e5dd7070Spatrick
2103e5dd7070Spatrick if (ArraySize && *ArraySize &&
2104e5dd7070Spatrick (*ArraySize)->getType()->isNonOverloadPlaceholderType()) {
2105e5dd7070Spatrick ExprResult result = CheckPlaceholderExpr(*ArraySize);
2106e5dd7070Spatrick if (result.isInvalid()) return ExprError();
2107e5dd7070Spatrick ArraySize = result.get();
2108e5dd7070Spatrick }
2109e5dd7070Spatrick // C++98 5.3.4p6: "The expression in a direct-new-declarator shall have
2110e5dd7070Spatrick // integral or enumeration type with a non-negative value."
2111e5dd7070Spatrick // C++11 [expr.new]p6: The expression [...] shall be of integral or unscoped
2112e5dd7070Spatrick // enumeration type, or a class type for which a single non-explicit
2113e5dd7070Spatrick // conversion function to integral or unscoped enumeration type exists.
2114e5dd7070Spatrick // C++1y [expr.new]p6: The expression [...] is implicitly converted to
2115e5dd7070Spatrick // std::size_t.
2116*12c85518Srobert std::optional<uint64_t> KnownArraySize;
2117e5dd7070Spatrick if (ArraySize && *ArraySize && !(*ArraySize)->isTypeDependent()) {
2118e5dd7070Spatrick ExprResult ConvertedSize;
2119e5dd7070Spatrick if (getLangOpts().CPlusPlus14) {
2120e5dd7070Spatrick assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?");
2121e5dd7070Spatrick
2122e5dd7070Spatrick ConvertedSize = PerformImplicitConversion(*ArraySize, Context.getSizeType(),
2123e5dd7070Spatrick AA_Converting);
2124e5dd7070Spatrick
2125e5dd7070Spatrick if (!ConvertedSize.isInvalid() &&
2126e5dd7070Spatrick (*ArraySize)->getType()->getAs<RecordType>())
2127e5dd7070Spatrick // Diagnose the compatibility of this conversion.
2128e5dd7070Spatrick Diag(StartLoc, diag::warn_cxx98_compat_array_size_conversion)
2129e5dd7070Spatrick << (*ArraySize)->getType() << 0 << "'size_t'";
2130e5dd7070Spatrick } else {
2131e5dd7070Spatrick class SizeConvertDiagnoser : public ICEConvertDiagnoser {
2132e5dd7070Spatrick protected:
2133e5dd7070Spatrick Expr *ArraySize;
2134e5dd7070Spatrick
2135e5dd7070Spatrick public:
2136e5dd7070Spatrick SizeConvertDiagnoser(Expr *ArraySize)
2137e5dd7070Spatrick : ICEConvertDiagnoser(/*AllowScopedEnumerations*/false, false, false),
2138e5dd7070Spatrick ArraySize(ArraySize) {}
2139e5dd7070Spatrick
2140e5dd7070Spatrick SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
2141e5dd7070Spatrick QualType T) override {
2142e5dd7070Spatrick return S.Diag(Loc, diag::err_array_size_not_integral)
2143e5dd7070Spatrick << S.getLangOpts().CPlusPlus11 << T;
2144e5dd7070Spatrick }
2145e5dd7070Spatrick
2146e5dd7070Spatrick SemaDiagnosticBuilder diagnoseIncomplete(
2147e5dd7070Spatrick Sema &S, SourceLocation Loc, QualType T) override {
2148e5dd7070Spatrick return S.Diag(Loc, diag::err_array_size_incomplete_type)
2149e5dd7070Spatrick << T << ArraySize->getSourceRange();
2150e5dd7070Spatrick }
2151e5dd7070Spatrick
2152e5dd7070Spatrick SemaDiagnosticBuilder diagnoseExplicitConv(
2153e5dd7070Spatrick Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
2154e5dd7070Spatrick return S.Diag(Loc, diag::err_array_size_explicit_conversion) << T << ConvTy;
2155e5dd7070Spatrick }
2156e5dd7070Spatrick
2157e5dd7070Spatrick SemaDiagnosticBuilder noteExplicitConv(
2158e5dd7070Spatrick Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
2159e5dd7070Spatrick return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
2160e5dd7070Spatrick << ConvTy->isEnumeralType() << ConvTy;
2161e5dd7070Spatrick }
2162e5dd7070Spatrick
2163e5dd7070Spatrick SemaDiagnosticBuilder diagnoseAmbiguous(
2164e5dd7070Spatrick Sema &S, SourceLocation Loc, QualType T) override {
2165e5dd7070Spatrick return S.Diag(Loc, diag::err_array_size_ambiguous_conversion) << T;
2166e5dd7070Spatrick }
2167e5dd7070Spatrick
2168e5dd7070Spatrick SemaDiagnosticBuilder noteAmbiguous(
2169e5dd7070Spatrick Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
2170e5dd7070Spatrick return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
2171e5dd7070Spatrick << ConvTy->isEnumeralType() << ConvTy;
2172e5dd7070Spatrick }
2173e5dd7070Spatrick
2174e5dd7070Spatrick SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc,
2175e5dd7070Spatrick QualType T,
2176e5dd7070Spatrick QualType ConvTy) override {
2177e5dd7070Spatrick return S.Diag(Loc,
2178e5dd7070Spatrick S.getLangOpts().CPlusPlus11
2179e5dd7070Spatrick ? diag::warn_cxx98_compat_array_size_conversion
2180e5dd7070Spatrick : diag::ext_array_size_conversion)
2181e5dd7070Spatrick << T << ConvTy->isEnumeralType() << ConvTy;
2182e5dd7070Spatrick }
2183e5dd7070Spatrick } SizeDiagnoser(*ArraySize);
2184e5dd7070Spatrick
2185e5dd7070Spatrick ConvertedSize = PerformContextualImplicitConversion(StartLoc, *ArraySize,
2186e5dd7070Spatrick SizeDiagnoser);
2187e5dd7070Spatrick }
2188e5dd7070Spatrick if (ConvertedSize.isInvalid())
2189e5dd7070Spatrick return ExprError();
2190e5dd7070Spatrick
2191e5dd7070Spatrick ArraySize = ConvertedSize.get();
2192e5dd7070Spatrick QualType SizeType = (*ArraySize)->getType();
2193e5dd7070Spatrick
2194e5dd7070Spatrick if (!SizeType->isIntegralOrUnscopedEnumerationType())
2195e5dd7070Spatrick return ExprError();
2196e5dd7070Spatrick
2197e5dd7070Spatrick // C++98 [expr.new]p7:
2198e5dd7070Spatrick // The expression in a direct-new-declarator shall have integral type
2199e5dd7070Spatrick // with a non-negative value.
2200e5dd7070Spatrick //
2201e5dd7070Spatrick // Let's see if this is a constant < 0. If so, we reject it out of hand,
2202e5dd7070Spatrick // per CWG1464. Otherwise, if it's not a constant, we must have an
2203e5dd7070Spatrick // unparenthesized array type.
2204*12c85518Srobert
2205e5dd7070Spatrick // We've already performed any required implicit conversion to integer or
2206e5dd7070Spatrick // unscoped enumeration type.
2207e5dd7070Spatrick // FIXME: Per CWG1464, we are required to check the value prior to
2208e5dd7070Spatrick // converting to size_t. This will never find a negative array size in
2209e5dd7070Spatrick // C++14 onwards, because Value is always unsigned here!
2210*12c85518Srobert if (std::optional<llvm::APSInt> Value =
2211a9ac8606Spatrick (*ArraySize)->getIntegerConstantExpr(Context)) {
2212a9ac8606Spatrick if (Value->isSigned() && Value->isNegative()) {
2213e5dd7070Spatrick return ExprError(Diag((*ArraySize)->getBeginLoc(),
2214e5dd7070Spatrick diag::err_typecheck_negative_array_size)
2215e5dd7070Spatrick << (*ArraySize)->getSourceRange());
2216e5dd7070Spatrick }
2217e5dd7070Spatrick
2218e5dd7070Spatrick if (!AllocType->isDependentType()) {
2219*12c85518Srobert unsigned ActiveSizeBits =
2220*12c85518Srobert ConstantArrayType::getNumAddressingBits(Context, AllocType, *Value);
2221e5dd7070Spatrick if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context))
2222e5dd7070Spatrick return ExprError(
2223e5dd7070Spatrick Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large)
2224a9ac8606Spatrick << toString(*Value, 10) << (*ArraySize)->getSourceRange());
2225e5dd7070Spatrick }
2226e5dd7070Spatrick
2227a9ac8606Spatrick KnownArraySize = Value->getZExtValue();
2228e5dd7070Spatrick } else if (TypeIdParens.isValid()) {
2229e5dd7070Spatrick // Can't have dynamic array size when the type-id is in parentheses.
2230e5dd7070Spatrick Diag((*ArraySize)->getBeginLoc(), diag::ext_new_paren_array_nonconst)
2231e5dd7070Spatrick << (*ArraySize)->getSourceRange()
2232e5dd7070Spatrick << FixItHint::CreateRemoval(TypeIdParens.getBegin())
2233e5dd7070Spatrick << FixItHint::CreateRemoval(TypeIdParens.getEnd());
2234e5dd7070Spatrick
2235e5dd7070Spatrick TypeIdParens = SourceRange();
2236e5dd7070Spatrick }
2237e5dd7070Spatrick
2238e5dd7070Spatrick // Note that we do *not* convert the argument in any way. It can
2239e5dd7070Spatrick // be signed, larger than size_t, whatever.
2240e5dd7070Spatrick }
2241e5dd7070Spatrick
2242e5dd7070Spatrick FunctionDecl *OperatorNew = nullptr;
2243e5dd7070Spatrick FunctionDecl *OperatorDelete = nullptr;
2244e5dd7070Spatrick unsigned Alignment =
2245e5dd7070Spatrick AllocType->isDependentType() ? 0 : Context.getTypeAlign(AllocType);
2246e5dd7070Spatrick unsigned NewAlignment = Context.getTargetInfo().getNewAlign();
2247e5dd7070Spatrick bool PassAlignment = getLangOpts().AlignedAllocation &&
2248e5dd7070Spatrick Alignment > NewAlignment;
2249e5dd7070Spatrick
2250e5dd7070Spatrick AllocationFunctionScope Scope = UseGlobal ? AFS_Global : AFS_Both;
2251e5dd7070Spatrick if (!AllocType->isDependentType() &&
2252e5dd7070Spatrick !Expr::hasAnyTypeDependentArguments(PlacementArgs) &&
2253e5dd7070Spatrick FindAllocationFunctions(
2254e5dd7070Spatrick StartLoc, SourceRange(PlacementLParen, PlacementRParen), Scope, Scope,
2255*12c85518Srobert AllocType, ArraySize.has_value(), PassAlignment, PlacementArgs,
2256e5dd7070Spatrick OperatorNew, OperatorDelete))
2257e5dd7070Spatrick return ExprError();
2258e5dd7070Spatrick
2259e5dd7070Spatrick // If this is an array allocation, compute whether the usual array
2260e5dd7070Spatrick // deallocation function for the type has a size_t parameter.
2261e5dd7070Spatrick bool UsualArrayDeleteWantsSize = false;
2262e5dd7070Spatrick if (ArraySize && !AllocType->isDependentType())
2263e5dd7070Spatrick UsualArrayDeleteWantsSize =
2264e5dd7070Spatrick doesUsualArrayDeleteWantSize(*this, StartLoc, AllocType);
2265e5dd7070Spatrick
2266e5dd7070Spatrick SmallVector<Expr *, 8> AllPlaceArgs;
2267e5dd7070Spatrick if (OperatorNew) {
2268ec727ea7Spatrick auto *Proto = OperatorNew->getType()->castAs<FunctionProtoType>();
2269e5dd7070Spatrick VariadicCallType CallType = Proto->isVariadic() ? VariadicFunction
2270e5dd7070Spatrick : VariadicDoesNotApply;
2271e5dd7070Spatrick
2272e5dd7070Spatrick // We've already converted the placement args, just fill in any default
2273e5dd7070Spatrick // arguments. Skip the first parameter because we don't have a corresponding
2274e5dd7070Spatrick // argument. Skip the second parameter too if we're passing in the
2275e5dd7070Spatrick // alignment; we've already filled it in.
2276ec727ea7Spatrick unsigned NumImplicitArgs = PassAlignment ? 2 : 1;
2277e5dd7070Spatrick if (GatherArgumentsForCall(PlacementLParen, OperatorNew, Proto,
2278ec727ea7Spatrick NumImplicitArgs, PlacementArgs, AllPlaceArgs,
2279ec727ea7Spatrick CallType))
2280e5dd7070Spatrick return ExprError();
2281e5dd7070Spatrick
2282e5dd7070Spatrick if (!AllPlaceArgs.empty())
2283e5dd7070Spatrick PlacementArgs = AllPlaceArgs;
2284e5dd7070Spatrick
2285ec727ea7Spatrick // We would like to perform some checking on the given `operator new` call,
2286ec727ea7Spatrick // but the PlacementArgs does not contain the implicit arguments,
2287ec727ea7Spatrick // namely allocation size and maybe allocation alignment,
2288ec727ea7Spatrick // so we need to conjure them.
2289e5dd7070Spatrick
2290ec727ea7Spatrick QualType SizeTy = Context.getSizeType();
2291ec727ea7Spatrick unsigned SizeTyWidth = Context.getTypeSize(SizeTy);
2292ec727ea7Spatrick
2293ec727ea7Spatrick llvm::APInt SingleEltSize(
2294ec727ea7Spatrick SizeTyWidth, Context.getTypeSizeInChars(AllocType).getQuantity());
2295ec727ea7Spatrick
2296ec727ea7Spatrick // How many bytes do we want to allocate here?
2297*12c85518Srobert std::optional<llvm::APInt> AllocationSize;
2298*12c85518Srobert if (!ArraySize && !AllocType->isDependentType()) {
2299ec727ea7Spatrick // For non-array operator new, we only want to allocate one element.
2300ec727ea7Spatrick AllocationSize = SingleEltSize;
2301*12c85518Srobert } else if (KnownArraySize && !AllocType->isDependentType()) {
2302ec727ea7Spatrick // For array operator new, only deal with static array size case.
2303ec727ea7Spatrick bool Overflow;
2304ec727ea7Spatrick AllocationSize = llvm::APInt(SizeTyWidth, *KnownArraySize)
2305ec727ea7Spatrick .umul_ov(SingleEltSize, Overflow);
2306ec727ea7Spatrick (void)Overflow;
2307ec727ea7Spatrick assert(
2308ec727ea7Spatrick !Overflow &&
2309ec727ea7Spatrick "Expected that all the overflows would have been handled already.");
2310ec727ea7Spatrick }
2311ec727ea7Spatrick
2312ec727ea7Spatrick IntegerLiteral AllocationSizeLiteral(
2313*12c85518Srobert Context, AllocationSize.value_or(llvm::APInt::getZero(SizeTyWidth)),
2314ec727ea7Spatrick SizeTy, SourceLocation());
2315ec727ea7Spatrick // Otherwise, if we failed to constant-fold the allocation size, we'll
2316ec727ea7Spatrick // just give up and pass-in something opaque, that isn't a null pointer.
2317a9ac8606Spatrick OpaqueValueExpr OpaqueAllocationSize(SourceLocation(), SizeTy, VK_PRValue,
2318ec727ea7Spatrick OK_Ordinary, /*SourceExpr=*/nullptr);
2319ec727ea7Spatrick
2320ec727ea7Spatrick // Let's synthesize the alignment argument in case we will need it.
2321ec727ea7Spatrick // Since we *really* want to allocate these on stack, this is slightly ugly
2322ec727ea7Spatrick // because there might not be a `std::align_val_t` type.
2323ec727ea7Spatrick EnumDecl *StdAlignValT = getStdAlignValT();
2324ec727ea7Spatrick QualType AlignValT =
2325ec727ea7Spatrick StdAlignValT ? Context.getTypeDeclType(StdAlignValT) : SizeTy;
2326ec727ea7Spatrick IntegerLiteral AlignmentLiteral(
2327ec727ea7Spatrick Context,
2328ec727ea7Spatrick llvm::APInt(Context.getTypeSize(SizeTy),
2329ec727ea7Spatrick Alignment / Context.getCharWidth()),
2330ec727ea7Spatrick SizeTy, SourceLocation());
2331ec727ea7Spatrick ImplicitCastExpr DesiredAlignment(ImplicitCastExpr::OnStack, AlignValT,
2332ec727ea7Spatrick CK_IntegralCast, &AlignmentLiteral,
2333a9ac8606Spatrick VK_PRValue, FPOptionsOverride());
2334ec727ea7Spatrick
2335ec727ea7Spatrick // Adjust placement args by prepending conjured size and alignment exprs.
2336ec727ea7Spatrick llvm::SmallVector<Expr *, 8> CallArgs;
2337ec727ea7Spatrick CallArgs.reserve(NumImplicitArgs + PlacementArgs.size());
2338*12c85518Srobert CallArgs.emplace_back(AllocationSize
2339ec727ea7Spatrick ? static_cast<Expr *>(&AllocationSizeLiteral)
2340ec727ea7Spatrick : &OpaqueAllocationSize);
2341ec727ea7Spatrick if (PassAlignment)
2342ec727ea7Spatrick CallArgs.emplace_back(&DesiredAlignment);
2343ec727ea7Spatrick CallArgs.insert(CallArgs.end(), PlacementArgs.begin(), PlacementArgs.end());
2344ec727ea7Spatrick
2345ec727ea7Spatrick DiagnoseSentinelCalls(OperatorNew, PlacementLParen, CallArgs);
2346ec727ea7Spatrick
2347ec727ea7Spatrick checkCall(OperatorNew, Proto, /*ThisArg=*/nullptr, CallArgs,
2348ec727ea7Spatrick /*IsMemberFunction=*/false, StartLoc, Range, CallType);
2349e5dd7070Spatrick
2350e5dd7070Spatrick // Warn if the type is over-aligned and is being allocated by (unaligned)
2351e5dd7070Spatrick // global operator new.
2352e5dd7070Spatrick if (PlacementArgs.empty() && !PassAlignment &&
2353e5dd7070Spatrick (OperatorNew->isImplicit() ||
2354e5dd7070Spatrick (OperatorNew->getBeginLoc().isValid() &&
2355e5dd7070Spatrick getSourceManager().isInSystemHeader(OperatorNew->getBeginLoc())))) {
2356e5dd7070Spatrick if (Alignment > NewAlignment)
2357e5dd7070Spatrick Diag(StartLoc, diag::warn_overaligned_type)
2358e5dd7070Spatrick << AllocType
2359e5dd7070Spatrick << unsigned(Alignment / Context.getCharWidth())
2360e5dd7070Spatrick << unsigned(NewAlignment / Context.getCharWidth());
2361e5dd7070Spatrick }
2362e5dd7070Spatrick }
2363e5dd7070Spatrick
2364e5dd7070Spatrick // Array 'new' can't have any initializers except empty parentheses.
2365e5dd7070Spatrick // Initializer lists are also allowed, in C++11. Rely on the parser for the
2366e5dd7070Spatrick // dialect distinction.
2367e5dd7070Spatrick if (ArraySize && !isLegalArrayNewInitializer(initStyle, Initializer)) {
2368*12c85518Srobert SourceRange InitRange(Exprs.front()->getBeginLoc(),
2369*12c85518Srobert Exprs.back()->getEndLoc());
2370e5dd7070Spatrick Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
2371e5dd7070Spatrick return ExprError();
2372e5dd7070Spatrick }
2373e5dd7070Spatrick
2374e5dd7070Spatrick // If we can perform the initialization, and we've not already done so,
2375e5dd7070Spatrick // do it now.
2376e5dd7070Spatrick if (!AllocType->isDependentType() &&
2377*12c85518Srobert !Expr::hasAnyTypeDependentArguments(Exprs)) {
2378e5dd7070Spatrick // The type we initialize is the complete type, including the array bound.
2379e5dd7070Spatrick QualType InitType;
2380e5dd7070Spatrick if (KnownArraySize)
2381e5dd7070Spatrick InitType = Context.getConstantArrayType(
2382e5dd7070Spatrick AllocType,
2383e5dd7070Spatrick llvm::APInt(Context.getTypeSize(Context.getSizeType()),
2384e5dd7070Spatrick *KnownArraySize),
2385e5dd7070Spatrick *ArraySize, ArrayType::Normal, 0);
2386e5dd7070Spatrick else if (ArraySize)
2387e5dd7070Spatrick InitType =
2388e5dd7070Spatrick Context.getIncompleteArrayType(AllocType, ArrayType::Normal, 0);
2389e5dd7070Spatrick else
2390e5dd7070Spatrick InitType = AllocType;
2391e5dd7070Spatrick
2392e5dd7070Spatrick InitializedEntity Entity
2393e5dd7070Spatrick = InitializedEntity::InitializeNew(StartLoc, InitType);
2394*12c85518Srobert InitializationSequence InitSeq(*this, Entity, Kind, Exprs);
2395*12c85518Srobert ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, Exprs);
2396e5dd7070Spatrick if (FullInit.isInvalid())
2397e5dd7070Spatrick return ExprError();
2398e5dd7070Spatrick
2399e5dd7070Spatrick // FullInit is our initializer; strip off CXXBindTemporaryExprs, because
2400e5dd7070Spatrick // we don't want the initialized object to be destructed.
2401e5dd7070Spatrick // FIXME: We should not create these in the first place.
2402e5dd7070Spatrick if (CXXBindTemporaryExpr *Binder =
2403e5dd7070Spatrick dyn_cast_or_null<CXXBindTemporaryExpr>(FullInit.get()))
2404e5dd7070Spatrick FullInit = Binder->getSubExpr();
2405e5dd7070Spatrick
2406e5dd7070Spatrick Initializer = FullInit.get();
2407e5dd7070Spatrick
2408e5dd7070Spatrick // FIXME: If we have a KnownArraySize, check that the array bound of the
2409e5dd7070Spatrick // initializer is no greater than that constant value.
2410e5dd7070Spatrick
2411e5dd7070Spatrick if (ArraySize && !*ArraySize) {
2412e5dd7070Spatrick auto *CAT = Context.getAsConstantArrayType(Initializer->getType());
2413e5dd7070Spatrick if (CAT) {
2414e5dd7070Spatrick // FIXME: Track that the array size was inferred rather than explicitly
2415e5dd7070Spatrick // specified.
2416e5dd7070Spatrick ArraySize = IntegerLiteral::Create(
2417e5dd7070Spatrick Context, CAT->getSize(), Context.getSizeType(), TypeRange.getEnd());
2418e5dd7070Spatrick } else {
2419e5dd7070Spatrick Diag(TypeRange.getEnd(), diag::err_new_array_size_unknown_from_init)
2420e5dd7070Spatrick << Initializer->getSourceRange();
2421e5dd7070Spatrick }
2422e5dd7070Spatrick }
2423e5dd7070Spatrick }
2424e5dd7070Spatrick
2425e5dd7070Spatrick // Mark the new and delete operators as referenced.
2426e5dd7070Spatrick if (OperatorNew) {
2427e5dd7070Spatrick if (DiagnoseUseOfDecl(OperatorNew, StartLoc))
2428e5dd7070Spatrick return ExprError();
2429e5dd7070Spatrick MarkFunctionReferenced(StartLoc, OperatorNew);
2430e5dd7070Spatrick }
2431e5dd7070Spatrick if (OperatorDelete) {
2432e5dd7070Spatrick if (DiagnoseUseOfDecl(OperatorDelete, StartLoc))
2433e5dd7070Spatrick return ExprError();
2434e5dd7070Spatrick MarkFunctionReferenced(StartLoc, OperatorDelete);
2435e5dd7070Spatrick }
2436e5dd7070Spatrick
2437e5dd7070Spatrick return CXXNewExpr::Create(Context, UseGlobal, OperatorNew, OperatorDelete,
2438e5dd7070Spatrick PassAlignment, UsualArrayDeleteWantsSize,
2439e5dd7070Spatrick PlacementArgs, TypeIdParens, ArraySize, initStyle,
2440e5dd7070Spatrick Initializer, ResultType, AllocTypeInfo, Range,
2441e5dd7070Spatrick DirectInitRange);
2442e5dd7070Spatrick }
2443e5dd7070Spatrick
2444e5dd7070Spatrick /// Checks that a type is suitable as the allocated type
2445e5dd7070Spatrick /// in a new-expression.
CheckAllocatedType(QualType AllocType,SourceLocation Loc,SourceRange R)2446e5dd7070Spatrick bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
2447e5dd7070Spatrick SourceRange R) {
2448e5dd7070Spatrick // C++ 5.3.4p1: "[The] type shall be a complete object type, but not an
2449e5dd7070Spatrick // abstract class type or array thereof.
2450e5dd7070Spatrick if (AllocType->isFunctionType())
2451e5dd7070Spatrick return Diag(Loc, diag::err_bad_new_type)
2452e5dd7070Spatrick << AllocType << 0 << R;
2453e5dd7070Spatrick else if (AllocType->isReferenceType())
2454e5dd7070Spatrick return Diag(Loc, diag::err_bad_new_type)
2455e5dd7070Spatrick << AllocType << 1 << R;
2456e5dd7070Spatrick else if (!AllocType->isDependentType() &&
2457ec727ea7Spatrick RequireCompleteSizedType(
2458ec727ea7Spatrick Loc, AllocType, diag::err_new_incomplete_or_sizeless_type, R))
2459e5dd7070Spatrick return true;
2460e5dd7070Spatrick else if (RequireNonAbstractType(Loc, AllocType,
2461e5dd7070Spatrick diag::err_allocation_of_abstract_type))
2462e5dd7070Spatrick return true;
2463e5dd7070Spatrick else if (AllocType->isVariablyModifiedType())
2464e5dd7070Spatrick return Diag(Loc, diag::err_variably_modified_new_type)
2465e5dd7070Spatrick << AllocType;
2466e5dd7070Spatrick else if (AllocType.getAddressSpace() != LangAS::Default &&
2467e5dd7070Spatrick !getLangOpts().OpenCLCPlusPlus)
2468e5dd7070Spatrick return Diag(Loc, diag::err_address_space_qualified_new)
2469e5dd7070Spatrick << AllocType.getUnqualifiedType()
2470e5dd7070Spatrick << AllocType.getQualifiers().getAddressSpaceAttributePrintValue();
2471e5dd7070Spatrick else if (getLangOpts().ObjCAutoRefCount) {
2472e5dd7070Spatrick if (const ArrayType *AT = Context.getAsArrayType(AllocType)) {
2473e5dd7070Spatrick QualType BaseAllocType = Context.getBaseElementType(AT);
2474e5dd7070Spatrick if (BaseAllocType.getObjCLifetime() == Qualifiers::OCL_None &&
2475e5dd7070Spatrick BaseAllocType->isObjCLifetimeType())
2476e5dd7070Spatrick return Diag(Loc, diag::err_arc_new_array_without_ownership)
2477e5dd7070Spatrick << BaseAllocType;
2478e5dd7070Spatrick }
2479e5dd7070Spatrick }
2480e5dd7070Spatrick
2481e5dd7070Spatrick return false;
2482e5dd7070Spatrick }
2483e5dd7070Spatrick
resolveAllocationOverload(Sema & S,LookupResult & R,SourceRange Range,SmallVectorImpl<Expr * > & Args,bool & PassAlignment,FunctionDecl * & Operator,OverloadCandidateSet * AlignedCandidates,Expr * AlignArg,bool Diagnose)2484e5dd7070Spatrick static bool resolveAllocationOverload(
2485e5dd7070Spatrick Sema &S, LookupResult &R, SourceRange Range, SmallVectorImpl<Expr *> &Args,
2486e5dd7070Spatrick bool &PassAlignment, FunctionDecl *&Operator,
2487e5dd7070Spatrick OverloadCandidateSet *AlignedCandidates, Expr *AlignArg, bool Diagnose) {
2488e5dd7070Spatrick OverloadCandidateSet Candidates(R.getNameLoc(),
2489e5dd7070Spatrick OverloadCandidateSet::CSK_Normal);
2490e5dd7070Spatrick for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end();
2491e5dd7070Spatrick Alloc != AllocEnd; ++Alloc) {
2492e5dd7070Spatrick // Even member operator new/delete are implicitly treated as
2493e5dd7070Spatrick // static, so don't use AddMemberCandidate.
2494e5dd7070Spatrick NamedDecl *D = (*Alloc)->getUnderlyingDecl();
2495e5dd7070Spatrick
2496e5dd7070Spatrick if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl>(D)) {
2497e5dd7070Spatrick S.AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(),
2498e5dd7070Spatrick /*ExplicitTemplateArgs=*/nullptr, Args,
2499e5dd7070Spatrick Candidates,
2500e5dd7070Spatrick /*SuppressUserConversions=*/false);
2501e5dd7070Spatrick continue;
2502e5dd7070Spatrick }
2503e5dd7070Spatrick
2504e5dd7070Spatrick FunctionDecl *Fn = cast<FunctionDecl>(D);
2505e5dd7070Spatrick S.AddOverloadCandidate(Fn, Alloc.getPair(), Args, Candidates,
2506e5dd7070Spatrick /*SuppressUserConversions=*/false);
2507e5dd7070Spatrick }
2508e5dd7070Spatrick
2509e5dd7070Spatrick // Do the resolution.
2510e5dd7070Spatrick OverloadCandidateSet::iterator Best;
2511e5dd7070Spatrick switch (Candidates.BestViableFunction(S, R.getNameLoc(), Best)) {
2512e5dd7070Spatrick case OR_Success: {
2513e5dd7070Spatrick // Got one!
2514e5dd7070Spatrick FunctionDecl *FnDecl = Best->Function;
2515e5dd7070Spatrick if (S.CheckAllocationAccess(R.getNameLoc(), Range, R.getNamingClass(),
2516e5dd7070Spatrick Best->FoundDecl) == Sema::AR_inaccessible)
2517e5dd7070Spatrick return true;
2518e5dd7070Spatrick
2519e5dd7070Spatrick Operator = FnDecl;
2520e5dd7070Spatrick return false;
2521e5dd7070Spatrick }
2522e5dd7070Spatrick
2523e5dd7070Spatrick case OR_No_Viable_Function:
2524e5dd7070Spatrick // C++17 [expr.new]p13:
2525e5dd7070Spatrick // If no matching function is found and the allocated object type has
2526e5dd7070Spatrick // new-extended alignment, the alignment argument is removed from the
2527e5dd7070Spatrick // argument list, and overload resolution is performed again.
2528e5dd7070Spatrick if (PassAlignment) {
2529e5dd7070Spatrick PassAlignment = false;
2530e5dd7070Spatrick AlignArg = Args[1];
2531e5dd7070Spatrick Args.erase(Args.begin() + 1);
2532e5dd7070Spatrick return resolveAllocationOverload(S, R, Range, Args, PassAlignment,
2533e5dd7070Spatrick Operator, &Candidates, AlignArg,
2534e5dd7070Spatrick Diagnose);
2535e5dd7070Spatrick }
2536e5dd7070Spatrick
2537e5dd7070Spatrick // MSVC will fall back on trying to find a matching global operator new
2538e5dd7070Spatrick // if operator new[] cannot be found. Also, MSVC will leak by not
2539e5dd7070Spatrick // generating a call to operator delete or operator delete[], but we
2540e5dd7070Spatrick // will not replicate that bug.
2541e5dd7070Spatrick // FIXME: Find out how this interacts with the std::align_val_t fallback
2542e5dd7070Spatrick // once MSVC implements it.
2543e5dd7070Spatrick if (R.getLookupName().getCXXOverloadedOperator() == OO_Array_New &&
2544e5dd7070Spatrick S.Context.getLangOpts().MSVCCompat) {
2545e5dd7070Spatrick R.clear();
2546e5dd7070Spatrick R.setLookupName(S.Context.DeclarationNames.getCXXOperatorName(OO_New));
2547e5dd7070Spatrick S.LookupQualifiedName(R, S.Context.getTranslationUnitDecl());
2548e5dd7070Spatrick // FIXME: This will give bad diagnostics pointing at the wrong functions.
2549e5dd7070Spatrick return resolveAllocationOverload(S, R, Range, Args, PassAlignment,
2550e5dd7070Spatrick Operator, /*Candidates=*/nullptr,
2551e5dd7070Spatrick /*AlignArg=*/nullptr, Diagnose);
2552e5dd7070Spatrick }
2553e5dd7070Spatrick
2554e5dd7070Spatrick if (Diagnose) {
2555a9ac8606Spatrick // If this is an allocation of the form 'new (p) X' for some object
2556a9ac8606Spatrick // pointer p (or an expression that will decay to such a pointer),
2557a9ac8606Spatrick // diagnose the missing inclusion of <new>.
2558a9ac8606Spatrick if (!R.isClassLookup() && Args.size() == 2 &&
2559a9ac8606Spatrick (Args[1]->getType()->isObjectPointerType() ||
2560a9ac8606Spatrick Args[1]->getType()->isArrayType())) {
2561a9ac8606Spatrick S.Diag(R.getNameLoc(), diag::err_need_header_before_placement_new)
2562a9ac8606Spatrick << R.getLookupName() << Range;
2563a9ac8606Spatrick // Listing the candidates is unlikely to be useful; skip it.
2564a9ac8606Spatrick return true;
2565a9ac8606Spatrick }
2566e5dd7070Spatrick
2567a9ac8606Spatrick // Finish checking all candidates before we note any. This checking can
2568a9ac8606Spatrick // produce additional diagnostics so can't be interleaved with our
2569a9ac8606Spatrick // emission of notes.
2570a9ac8606Spatrick //
2571a9ac8606Spatrick // For an aligned allocation, separately check the aligned and unaligned
2572a9ac8606Spatrick // candidates with their respective argument lists.
2573a9ac8606Spatrick SmallVector<OverloadCandidate*, 32> Cands;
2574a9ac8606Spatrick SmallVector<OverloadCandidate*, 32> AlignedCands;
2575a9ac8606Spatrick llvm::SmallVector<Expr*, 4> AlignedArgs;
2576e5dd7070Spatrick if (AlignedCandidates) {
2577e5dd7070Spatrick auto IsAligned = [](OverloadCandidate &C) {
2578e5dd7070Spatrick return C.Function->getNumParams() > 1 &&
2579e5dd7070Spatrick C.Function->getParamDecl(1)->getType()->isAlignValT();
2580e5dd7070Spatrick };
2581e5dd7070Spatrick auto IsUnaligned = [&](OverloadCandidate &C) { return !IsAligned(C); };
2582e5dd7070Spatrick
2583a9ac8606Spatrick AlignedArgs.reserve(Args.size() + 1);
2584a9ac8606Spatrick AlignedArgs.push_back(Args[0]);
2585a9ac8606Spatrick AlignedArgs.push_back(AlignArg);
2586a9ac8606Spatrick AlignedArgs.append(Args.begin() + 1, Args.end());
2587a9ac8606Spatrick AlignedCands = AlignedCandidates->CompleteCandidates(
2588a9ac8606Spatrick S, OCD_AllCandidates, AlignedArgs, R.getNameLoc(), IsAligned);
2589a9ac8606Spatrick
2590a9ac8606Spatrick Cands = Candidates.CompleteCandidates(S, OCD_AllCandidates, Args,
2591a9ac8606Spatrick R.getNameLoc(), IsUnaligned);
2592e5dd7070Spatrick } else {
2593a9ac8606Spatrick Cands = Candidates.CompleteCandidates(S, OCD_AllCandidates, Args,
2594a9ac8606Spatrick R.getNameLoc());
2595e5dd7070Spatrick }
2596a9ac8606Spatrick
2597a9ac8606Spatrick S.Diag(R.getNameLoc(), diag::err_ovl_no_viable_function_in_call)
2598a9ac8606Spatrick << R.getLookupName() << Range;
2599a9ac8606Spatrick if (AlignedCandidates)
2600a9ac8606Spatrick AlignedCandidates->NoteCandidates(S, AlignedArgs, AlignedCands, "",
2601a9ac8606Spatrick R.getNameLoc());
2602a9ac8606Spatrick Candidates.NoteCandidates(S, Args, Cands, "", R.getNameLoc());
2603e5dd7070Spatrick }
2604e5dd7070Spatrick return true;
2605e5dd7070Spatrick
2606e5dd7070Spatrick case OR_Ambiguous:
2607e5dd7070Spatrick if (Diagnose) {
2608e5dd7070Spatrick Candidates.NoteCandidates(
2609e5dd7070Spatrick PartialDiagnosticAt(R.getNameLoc(),
2610e5dd7070Spatrick S.PDiag(diag::err_ovl_ambiguous_call)
2611e5dd7070Spatrick << R.getLookupName() << Range),
2612e5dd7070Spatrick S, OCD_AmbiguousCandidates, Args);
2613e5dd7070Spatrick }
2614e5dd7070Spatrick return true;
2615e5dd7070Spatrick
2616e5dd7070Spatrick case OR_Deleted: {
2617e5dd7070Spatrick if (Diagnose) {
2618e5dd7070Spatrick Candidates.NoteCandidates(
2619e5dd7070Spatrick PartialDiagnosticAt(R.getNameLoc(),
2620e5dd7070Spatrick S.PDiag(diag::err_ovl_deleted_call)
2621e5dd7070Spatrick << R.getLookupName() << Range),
2622e5dd7070Spatrick S, OCD_AllCandidates, Args);
2623e5dd7070Spatrick }
2624e5dd7070Spatrick return true;
2625e5dd7070Spatrick }
2626e5dd7070Spatrick }
2627e5dd7070Spatrick llvm_unreachable("Unreachable, bad result from BestViableFunction");
2628e5dd7070Spatrick }
2629e5dd7070Spatrick
FindAllocationFunctions(SourceLocation StartLoc,SourceRange Range,AllocationFunctionScope NewScope,AllocationFunctionScope DeleteScope,QualType AllocType,bool IsArray,bool & PassAlignment,MultiExprArg PlaceArgs,FunctionDecl * & OperatorNew,FunctionDecl * & OperatorDelete,bool Diagnose)2630e5dd7070Spatrick bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
2631e5dd7070Spatrick AllocationFunctionScope NewScope,
2632e5dd7070Spatrick AllocationFunctionScope DeleteScope,
2633e5dd7070Spatrick QualType AllocType, bool IsArray,
2634e5dd7070Spatrick bool &PassAlignment, MultiExprArg PlaceArgs,
2635e5dd7070Spatrick FunctionDecl *&OperatorNew,
2636e5dd7070Spatrick FunctionDecl *&OperatorDelete,
2637e5dd7070Spatrick bool Diagnose) {
2638e5dd7070Spatrick // --- Choosing an allocation function ---
2639e5dd7070Spatrick // C++ 5.3.4p8 - 14 & 18
2640e5dd7070Spatrick // 1) If looking in AFS_Global scope for allocation functions, only look in
2641e5dd7070Spatrick // the global scope. Else, if AFS_Class, only look in the scope of the
2642e5dd7070Spatrick // allocated class. If AFS_Both, look in both.
2643e5dd7070Spatrick // 2) If an array size is given, look for operator new[], else look for
2644e5dd7070Spatrick // operator new.
2645e5dd7070Spatrick // 3) The first argument is always size_t. Append the arguments from the
2646e5dd7070Spatrick // placement form.
2647e5dd7070Spatrick
2648e5dd7070Spatrick SmallVector<Expr*, 8> AllocArgs;
2649e5dd7070Spatrick AllocArgs.reserve((PassAlignment ? 2 : 1) + PlaceArgs.size());
2650e5dd7070Spatrick
2651e5dd7070Spatrick // We don't care about the actual value of these arguments.
2652e5dd7070Spatrick // FIXME: Should the Sema create the expression and embed it in the syntax
2653e5dd7070Spatrick // tree? Or should the consumer just recalculate the value?
2654e5dd7070Spatrick // FIXME: Using a dummy value will interact poorly with attribute enable_if.
2655*12c85518Srobert IntegerLiteral Size(
2656*12c85518Srobert Context,
2657*12c85518Srobert llvm::APInt::getZero(
2658*12c85518Srobert Context.getTargetInfo().getPointerWidth(LangAS::Default)),
2659*12c85518Srobert Context.getSizeType(), SourceLocation());
2660e5dd7070Spatrick AllocArgs.push_back(&Size);
2661e5dd7070Spatrick
2662e5dd7070Spatrick QualType AlignValT = Context.VoidTy;
2663e5dd7070Spatrick if (PassAlignment) {
2664e5dd7070Spatrick DeclareGlobalNewDelete();
2665e5dd7070Spatrick AlignValT = Context.getTypeDeclType(getStdAlignValT());
2666e5dd7070Spatrick }
2667e5dd7070Spatrick CXXScalarValueInitExpr Align(AlignValT, nullptr, SourceLocation());
2668e5dd7070Spatrick if (PassAlignment)
2669e5dd7070Spatrick AllocArgs.push_back(&Align);
2670e5dd7070Spatrick
2671e5dd7070Spatrick AllocArgs.insert(AllocArgs.end(), PlaceArgs.begin(), PlaceArgs.end());
2672e5dd7070Spatrick
2673e5dd7070Spatrick // C++ [expr.new]p8:
2674e5dd7070Spatrick // If the allocated type is a non-array type, the allocation
2675e5dd7070Spatrick // function's name is operator new and the deallocation function's
2676e5dd7070Spatrick // name is operator delete. If the allocated type is an array
2677e5dd7070Spatrick // type, the allocation function's name is operator new[] and the
2678e5dd7070Spatrick // deallocation function's name is operator delete[].
2679e5dd7070Spatrick DeclarationName NewName = Context.DeclarationNames.getCXXOperatorName(
2680e5dd7070Spatrick IsArray ? OO_Array_New : OO_New);
2681e5dd7070Spatrick
2682e5dd7070Spatrick QualType AllocElemType = Context.getBaseElementType(AllocType);
2683e5dd7070Spatrick
2684e5dd7070Spatrick // Find the allocation function.
2685e5dd7070Spatrick {
2686e5dd7070Spatrick LookupResult R(*this, NewName, StartLoc, LookupOrdinaryName);
2687e5dd7070Spatrick
2688e5dd7070Spatrick // C++1z [expr.new]p9:
2689e5dd7070Spatrick // If the new-expression begins with a unary :: operator, the allocation
2690e5dd7070Spatrick // function's name is looked up in the global scope. Otherwise, if the
2691e5dd7070Spatrick // allocated type is a class type T or array thereof, the allocation
2692e5dd7070Spatrick // function's name is looked up in the scope of T.
2693e5dd7070Spatrick if (AllocElemType->isRecordType() && NewScope != AFS_Global)
2694e5dd7070Spatrick LookupQualifiedName(R, AllocElemType->getAsCXXRecordDecl());
2695e5dd7070Spatrick
2696e5dd7070Spatrick // We can see ambiguity here if the allocation function is found in
2697e5dd7070Spatrick // multiple base classes.
2698e5dd7070Spatrick if (R.isAmbiguous())
2699e5dd7070Spatrick return true;
2700e5dd7070Spatrick
2701e5dd7070Spatrick // If this lookup fails to find the name, or if the allocated type is not
2702e5dd7070Spatrick // a class type, the allocation function's name is looked up in the
2703e5dd7070Spatrick // global scope.
2704e5dd7070Spatrick if (R.empty()) {
2705e5dd7070Spatrick if (NewScope == AFS_Class)
2706e5dd7070Spatrick return true;
2707e5dd7070Spatrick
2708e5dd7070Spatrick LookupQualifiedName(R, Context.getTranslationUnitDecl());
2709e5dd7070Spatrick }
2710e5dd7070Spatrick
2711e5dd7070Spatrick if (getLangOpts().OpenCLCPlusPlus && R.empty()) {
2712e5dd7070Spatrick if (PlaceArgs.empty()) {
2713e5dd7070Spatrick Diag(StartLoc, diag::err_openclcxx_not_supported) << "default new";
2714e5dd7070Spatrick } else {
2715e5dd7070Spatrick Diag(StartLoc, diag::err_openclcxx_placement_new);
2716e5dd7070Spatrick }
2717e5dd7070Spatrick return true;
2718e5dd7070Spatrick }
2719e5dd7070Spatrick
2720e5dd7070Spatrick assert(!R.empty() && "implicitly declared allocation functions not found");
2721e5dd7070Spatrick assert(!R.isAmbiguous() && "global allocation functions are ambiguous");
2722e5dd7070Spatrick
2723e5dd7070Spatrick // We do our own custom access checks below.
2724e5dd7070Spatrick R.suppressDiagnostics();
2725e5dd7070Spatrick
2726e5dd7070Spatrick if (resolveAllocationOverload(*this, R, Range, AllocArgs, PassAlignment,
2727e5dd7070Spatrick OperatorNew, /*Candidates=*/nullptr,
2728e5dd7070Spatrick /*AlignArg=*/nullptr, Diagnose))
2729e5dd7070Spatrick return true;
2730e5dd7070Spatrick }
2731e5dd7070Spatrick
2732e5dd7070Spatrick // We don't need an operator delete if we're running under -fno-exceptions.
2733e5dd7070Spatrick if (!getLangOpts().Exceptions) {
2734e5dd7070Spatrick OperatorDelete = nullptr;
2735e5dd7070Spatrick return false;
2736e5dd7070Spatrick }
2737e5dd7070Spatrick
2738e5dd7070Spatrick // Note, the name of OperatorNew might have been changed from array to
2739e5dd7070Spatrick // non-array by resolveAllocationOverload.
2740e5dd7070Spatrick DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
2741e5dd7070Spatrick OperatorNew->getDeclName().getCXXOverloadedOperator() == OO_Array_New
2742e5dd7070Spatrick ? OO_Array_Delete
2743e5dd7070Spatrick : OO_Delete);
2744e5dd7070Spatrick
2745e5dd7070Spatrick // C++ [expr.new]p19:
2746e5dd7070Spatrick //
2747e5dd7070Spatrick // If the new-expression begins with a unary :: operator, the
2748e5dd7070Spatrick // deallocation function's name is looked up in the global
2749e5dd7070Spatrick // scope. Otherwise, if the allocated type is a class type T or an
2750e5dd7070Spatrick // array thereof, the deallocation function's name is looked up in
2751e5dd7070Spatrick // the scope of T. If this lookup fails to find the name, or if
2752e5dd7070Spatrick // the allocated type is not a class type or array thereof, the
2753e5dd7070Spatrick // deallocation function's name is looked up in the global scope.
2754e5dd7070Spatrick LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName);
2755e5dd7070Spatrick if (AllocElemType->isRecordType() && DeleteScope != AFS_Global) {
2756e5dd7070Spatrick auto *RD =
2757e5dd7070Spatrick cast<CXXRecordDecl>(AllocElemType->castAs<RecordType>()->getDecl());
2758e5dd7070Spatrick LookupQualifiedName(FoundDelete, RD);
2759e5dd7070Spatrick }
2760e5dd7070Spatrick if (FoundDelete.isAmbiguous())
2761e5dd7070Spatrick return true; // FIXME: clean up expressions?
2762e5dd7070Spatrick
2763a9ac8606Spatrick // Filter out any destroying operator deletes. We can't possibly call such a
2764a9ac8606Spatrick // function in this context, because we're handling the case where the object
2765a9ac8606Spatrick // was not successfully constructed.
2766a9ac8606Spatrick // FIXME: This is not covered by the language rules yet.
2767a9ac8606Spatrick {
2768a9ac8606Spatrick LookupResult::Filter Filter = FoundDelete.makeFilter();
2769a9ac8606Spatrick while (Filter.hasNext()) {
2770a9ac8606Spatrick auto *FD = dyn_cast<FunctionDecl>(Filter.next()->getUnderlyingDecl());
2771a9ac8606Spatrick if (FD && FD->isDestroyingOperatorDelete())
2772a9ac8606Spatrick Filter.erase();
2773a9ac8606Spatrick }
2774a9ac8606Spatrick Filter.done();
2775a9ac8606Spatrick }
2776a9ac8606Spatrick
2777e5dd7070Spatrick bool FoundGlobalDelete = FoundDelete.empty();
2778e5dd7070Spatrick if (FoundDelete.empty()) {
2779a9ac8606Spatrick FoundDelete.clear(LookupOrdinaryName);
2780a9ac8606Spatrick
2781e5dd7070Spatrick if (DeleteScope == AFS_Class)
2782e5dd7070Spatrick return true;
2783e5dd7070Spatrick
2784e5dd7070Spatrick DeclareGlobalNewDelete();
2785e5dd7070Spatrick LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl());
2786e5dd7070Spatrick }
2787e5dd7070Spatrick
2788e5dd7070Spatrick FoundDelete.suppressDiagnostics();
2789e5dd7070Spatrick
2790e5dd7070Spatrick SmallVector<std::pair<DeclAccessPair,FunctionDecl*>, 2> Matches;
2791e5dd7070Spatrick
2792e5dd7070Spatrick // Whether we're looking for a placement operator delete is dictated
2793e5dd7070Spatrick // by whether we selected a placement operator new, not by whether
2794e5dd7070Spatrick // we had explicit placement arguments. This matters for things like
2795e5dd7070Spatrick // struct A { void *operator new(size_t, int = 0); ... };
2796e5dd7070Spatrick // A *a = new A()
2797e5dd7070Spatrick //
2798e5dd7070Spatrick // We don't have any definition for what a "placement allocation function"
2799e5dd7070Spatrick // is, but we assume it's any allocation function whose
2800e5dd7070Spatrick // parameter-declaration-clause is anything other than (size_t).
2801e5dd7070Spatrick //
2802e5dd7070Spatrick // FIXME: Should (size_t, std::align_val_t) also be considered non-placement?
2803e5dd7070Spatrick // This affects whether an exception from the constructor of an overaligned
2804e5dd7070Spatrick // type uses the sized or non-sized form of aligned operator delete.
2805e5dd7070Spatrick bool isPlacementNew = !PlaceArgs.empty() || OperatorNew->param_size() != 1 ||
2806e5dd7070Spatrick OperatorNew->isVariadic();
2807e5dd7070Spatrick
2808e5dd7070Spatrick if (isPlacementNew) {
2809e5dd7070Spatrick // C++ [expr.new]p20:
2810e5dd7070Spatrick // A declaration of a placement deallocation function matches the
2811e5dd7070Spatrick // declaration of a placement allocation function if it has the
2812e5dd7070Spatrick // same number of parameters and, after parameter transformations
2813e5dd7070Spatrick // (8.3.5), all parameter types except the first are
2814e5dd7070Spatrick // identical. [...]
2815e5dd7070Spatrick //
2816e5dd7070Spatrick // To perform this comparison, we compute the function type that
2817e5dd7070Spatrick // the deallocation function should have, and use that type both
2818e5dd7070Spatrick // for template argument deduction and for comparison purposes.
2819e5dd7070Spatrick QualType ExpectedFunctionType;
2820e5dd7070Spatrick {
2821ec727ea7Spatrick auto *Proto = OperatorNew->getType()->castAs<FunctionProtoType>();
2822e5dd7070Spatrick
2823e5dd7070Spatrick SmallVector<QualType, 4> ArgTypes;
2824e5dd7070Spatrick ArgTypes.push_back(Context.VoidPtrTy);
2825e5dd7070Spatrick for (unsigned I = 1, N = Proto->getNumParams(); I < N; ++I)
2826e5dd7070Spatrick ArgTypes.push_back(Proto->getParamType(I));
2827e5dd7070Spatrick
2828e5dd7070Spatrick FunctionProtoType::ExtProtoInfo EPI;
2829e5dd7070Spatrick // FIXME: This is not part of the standard's rule.
2830e5dd7070Spatrick EPI.Variadic = Proto->isVariadic();
2831e5dd7070Spatrick
2832e5dd7070Spatrick ExpectedFunctionType
2833e5dd7070Spatrick = Context.getFunctionType(Context.VoidTy, ArgTypes, EPI);
2834e5dd7070Spatrick }
2835e5dd7070Spatrick
2836e5dd7070Spatrick for (LookupResult::iterator D = FoundDelete.begin(),
2837e5dd7070Spatrick DEnd = FoundDelete.end();
2838e5dd7070Spatrick D != DEnd; ++D) {
2839e5dd7070Spatrick FunctionDecl *Fn = nullptr;
2840e5dd7070Spatrick if (FunctionTemplateDecl *FnTmpl =
2841e5dd7070Spatrick dyn_cast<FunctionTemplateDecl>((*D)->getUnderlyingDecl())) {
2842e5dd7070Spatrick // Perform template argument deduction to try to match the
2843e5dd7070Spatrick // expected function type.
2844e5dd7070Spatrick TemplateDeductionInfo Info(StartLoc);
2845e5dd7070Spatrick if (DeduceTemplateArguments(FnTmpl, nullptr, ExpectedFunctionType, Fn,
2846e5dd7070Spatrick Info))
2847e5dd7070Spatrick continue;
2848e5dd7070Spatrick } else
2849e5dd7070Spatrick Fn = cast<FunctionDecl>((*D)->getUnderlyingDecl());
2850e5dd7070Spatrick
2851e5dd7070Spatrick if (Context.hasSameType(adjustCCAndNoReturn(Fn->getType(),
2852e5dd7070Spatrick ExpectedFunctionType,
2853e5dd7070Spatrick /*AdjustExcpetionSpec*/true),
2854e5dd7070Spatrick ExpectedFunctionType))
2855e5dd7070Spatrick Matches.push_back(std::make_pair(D.getPair(), Fn));
2856e5dd7070Spatrick }
2857e5dd7070Spatrick
2858e5dd7070Spatrick if (getLangOpts().CUDA)
2859*12c85518Srobert EraseUnwantedCUDAMatches(getCurFunctionDecl(/*AllowLambda=*/true),
2860*12c85518Srobert Matches);
2861e5dd7070Spatrick } else {
2862e5dd7070Spatrick // C++1y [expr.new]p22:
2863e5dd7070Spatrick // For a non-placement allocation function, the normal deallocation
2864e5dd7070Spatrick // function lookup is used
2865e5dd7070Spatrick //
2866e5dd7070Spatrick // Per [expr.delete]p10, this lookup prefers a member operator delete
2867e5dd7070Spatrick // without a size_t argument, but prefers a non-member operator delete
2868e5dd7070Spatrick // with a size_t where possible (which it always is in this case).
2869e5dd7070Spatrick llvm::SmallVector<UsualDeallocFnInfo, 4> BestDeallocFns;
2870e5dd7070Spatrick UsualDeallocFnInfo Selected = resolveDeallocationOverload(
2871e5dd7070Spatrick *this, FoundDelete, /*WantSize*/ FoundGlobalDelete,
2872e5dd7070Spatrick /*WantAlign*/ hasNewExtendedAlignment(*this, AllocElemType),
2873e5dd7070Spatrick &BestDeallocFns);
2874e5dd7070Spatrick if (Selected)
2875e5dd7070Spatrick Matches.push_back(std::make_pair(Selected.Found, Selected.FD));
2876e5dd7070Spatrick else {
2877e5dd7070Spatrick // If we failed to select an operator, all remaining functions are viable
2878e5dd7070Spatrick // but ambiguous.
2879e5dd7070Spatrick for (auto Fn : BestDeallocFns)
2880e5dd7070Spatrick Matches.push_back(std::make_pair(Fn.Found, Fn.FD));
2881e5dd7070Spatrick }
2882e5dd7070Spatrick }
2883e5dd7070Spatrick
2884e5dd7070Spatrick // C++ [expr.new]p20:
2885e5dd7070Spatrick // [...] If the lookup finds a single matching deallocation
2886e5dd7070Spatrick // function, that function will be called; otherwise, no
2887e5dd7070Spatrick // deallocation function will be called.
2888e5dd7070Spatrick if (Matches.size() == 1) {
2889e5dd7070Spatrick OperatorDelete = Matches[0].second;
2890e5dd7070Spatrick
2891e5dd7070Spatrick // C++1z [expr.new]p23:
2892e5dd7070Spatrick // If the lookup finds a usual deallocation function (3.7.4.2)
2893e5dd7070Spatrick // with a parameter of type std::size_t and that function, considered
2894e5dd7070Spatrick // as a placement deallocation function, would have been
2895e5dd7070Spatrick // selected as a match for the allocation function, the program
2896e5dd7070Spatrick // is ill-formed.
2897e5dd7070Spatrick if (getLangOpts().CPlusPlus11 && isPlacementNew &&
2898e5dd7070Spatrick isNonPlacementDeallocationFunction(*this, OperatorDelete)) {
2899e5dd7070Spatrick UsualDeallocFnInfo Info(*this,
2900e5dd7070Spatrick DeclAccessPair::make(OperatorDelete, AS_public));
2901e5dd7070Spatrick // Core issue, per mail to core reflector, 2016-10-09:
2902e5dd7070Spatrick // If this is a member operator delete, and there is a corresponding
2903e5dd7070Spatrick // non-sized member operator delete, this isn't /really/ a sized
2904e5dd7070Spatrick // deallocation function, it just happens to have a size_t parameter.
2905e5dd7070Spatrick bool IsSizedDelete = Info.HasSizeT;
2906e5dd7070Spatrick if (IsSizedDelete && !FoundGlobalDelete) {
2907e5dd7070Spatrick auto NonSizedDelete =
2908e5dd7070Spatrick resolveDeallocationOverload(*this, FoundDelete, /*WantSize*/false,
2909e5dd7070Spatrick /*WantAlign*/Info.HasAlignValT);
2910e5dd7070Spatrick if (NonSizedDelete && !NonSizedDelete.HasSizeT &&
2911e5dd7070Spatrick NonSizedDelete.HasAlignValT == Info.HasAlignValT)
2912e5dd7070Spatrick IsSizedDelete = false;
2913e5dd7070Spatrick }
2914e5dd7070Spatrick
2915e5dd7070Spatrick if (IsSizedDelete) {
2916e5dd7070Spatrick SourceRange R = PlaceArgs.empty()
2917e5dd7070Spatrick ? SourceRange()
2918e5dd7070Spatrick : SourceRange(PlaceArgs.front()->getBeginLoc(),
2919e5dd7070Spatrick PlaceArgs.back()->getEndLoc());
2920e5dd7070Spatrick Diag(StartLoc, diag::err_placement_new_non_placement_delete) << R;
2921e5dd7070Spatrick if (!OperatorDelete->isImplicit())
2922e5dd7070Spatrick Diag(OperatorDelete->getLocation(), diag::note_previous_decl)
2923e5dd7070Spatrick << DeleteName;
2924e5dd7070Spatrick }
2925e5dd7070Spatrick }
2926e5dd7070Spatrick
2927e5dd7070Spatrick CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(),
2928e5dd7070Spatrick Matches[0].first);
2929e5dd7070Spatrick } else if (!Matches.empty()) {
2930e5dd7070Spatrick // We found multiple suitable operators. Per [expr.new]p20, that means we
2931e5dd7070Spatrick // call no 'operator delete' function, but we should at least warn the user.
2932e5dd7070Spatrick // FIXME: Suppress this warning if the construction cannot throw.
2933e5dd7070Spatrick Diag(StartLoc, diag::warn_ambiguous_suitable_delete_function_found)
2934e5dd7070Spatrick << DeleteName << AllocElemType;
2935e5dd7070Spatrick
2936e5dd7070Spatrick for (auto &Match : Matches)
2937e5dd7070Spatrick Diag(Match.second->getLocation(),
2938e5dd7070Spatrick diag::note_member_declared_here) << DeleteName;
2939e5dd7070Spatrick }
2940e5dd7070Spatrick
2941e5dd7070Spatrick return false;
2942e5dd7070Spatrick }
2943e5dd7070Spatrick
2944e5dd7070Spatrick /// DeclareGlobalNewDelete - Declare the global forms of operator new and
2945e5dd7070Spatrick /// delete. These are:
2946e5dd7070Spatrick /// @code
2947e5dd7070Spatrick /// // C++03:
2948e5dd7070Spatrick /// void* operator new(std::size_t) throw(std::bad_alloc);
2949e5dd7070Spatrick /// void* operator new[](std::size_t) throw(std::bad_alloc);
2950e5dd7070Spatrick /// void operator delete(void *) throw();
2951e5dd7070Spatrick /// void operator delete[](void *) throw();
2952e5dd7070Spatrick /// // C++11:
2953e5dd7070Spatrick /// void* operator new(std::size_t);
2954e5dd7070Spatrick /// void* operator new[](std::size_t);
2955e5dd7070Spatrick /// void operator delete(void *) noexcept;
2956e5dd7070Spatrick /// void operator delete[](void *) noexcept;
2957e5dd7070Spatrick /// // C++1y:
2958e5dd7070Spatrick /// void* operator new(std::size_t);
2959e5dd7070Spatrick /// void* operator new[](std::size_t);
2960e5dd7070Spatrick /// void operator delete(void *) noexcept;
2961e5dd7070Spatrick /// void operator delete[](void *) noexcept;
2962e5dd7070Spatrick /// void operator delete(void *, std::size_t) noexcept;
2963e5dd7070Spatrick /// void operator delete[](void *, std::size_t) noexcept;
2964e5dd7070Spatrick /// @endcode
2965e5dd7070Spatrick /// Note that the placement and nothrow forms of new are *not* implicitly
2966e5dd7070Spatrick /// declared. Their use requires including \<new\>.
DeclareGlobalNewDelete()2967e5dd7070Spatrick void Sema::DeclareGlobalNewDelete() {
2968e5dd7070Spatrick if (GlobalNewDeleteDeclared)
2969e5dd7070Spatrick return;
2970e5dd7070Spatrick
2971e5dd7070Spatrick // The implicitly declared new and delete operators
2972e5dd7070Spatrick // are not supported in OpenCL.
2973e5dd7070Spatrick if (getLangOpts().OpenCLCPlusPlus)
2974e5dd7070Spatrick return;
2975e5dd7070Spatrick
2976*12c85518Srobert // C++ [basic.stc.dynamic.general]p2:
2977*12c85518Srobert // The library provides default definitions for the global allocation
2978*12c85518Srobert // and deallocation functions. Some global allocation and deallocation
2979*12c85518Srobert // functions are replaceable ([new.delete]); these are attached to the
2980*12c85518Srobert // global module ([module.unit]).
2981*12c85518Srobert if (getLangOpts().CPlusPlusModules && getCurrentModule())
2982*12c85518Srobert PushGlobalModuleFragment(SourceLocation(), /*IsImplicit=*/true);
2983*12c85518Srobert
2984e5dd7070Spatrick // C++ [basic.std.dynamic]p2:
2985e5dd7070Spatrick // [...] The following allocation and deallocation functions (18.4) are
2986e5dd7070Spatrick // implicitly declared in global scope in each translation unit of a
2987e5dd7070Spatrick // program
2988e5dd7070Spatrick //
2989e5dd7070Spatrick // C++03:
2990e5dd7070Spatrick // void* operator new(std::size_t) throw(std::bad_alloc);
2991e5dd7070Spatrick // void* operator new[](std::size_t) throw(std::bad_alloc);
2992e5dd7070Spatrick // void operator delete(void*) throw();
2993e5dd7070Spatrick // void operator delete[](void*) throw();
2994e5dd7070Spatrick // C++11:
2995e5dd7070Spatrick // void* operator new(std::size_t);
2996e5dd7070Spatrick // void* operator new[](std::size_t);
2997e5dd7070Spatrick // void operator delete(void*) noexcept;
2998e5dd7070Spatrick // void operator delete[](void*) noexcept;
2999e5dd7070Spatrick // C++1y:
3000e5dd7070Spatrick // void* operator new(std::size_t);
3001e5dd7070Spatrick // void* operator new[](std::size_t);
3002e5dd7070Spatrick // void operator delete(void*) noexcept;
3003e5dd7070Spatrick // void operator delete[](void*) noexcept;
3004e5dd7070Spatrick // void operator delete(void*, std::size_t) noexcept;
3005e5dd7070Spatrick // void operator delete[](void*, std::size_t) noexcept;
3006e5dd7070Spatrick //
3007e5dd7070Spatrick // These implicit declarations introduce only the function names operator
3008e5dd7070Spatrick // new, operator new[], operator delete, operator delete[].
3009e5dd7070Spatrick //
3010e5dd7070Spatrick // Here, we need to refer to std::bad_alloc, so we will implicitly declare
3011e5dd7070Spatrick // "std" or "bad_alloc" as necessary to form the exception specification.
3012e5dd7070Spatrick // However, we do not make these implicit declarations visible to name
3013e5dd7070Spatrick // lookup.
3014e5dd7070Spatrick if (!StdBadAlloc && !getLangOpts().CPlusPlus11) {
3015e5dd7070Spatrick // The "std::bad_alloc" class has not yet been declared, so build it
3016e5dd7070Spatrick // implicitly.
3017e5dd7070Spatrick StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class,
3018e5dd7070Spatrick getOrCreateStdNamespace(),
3019e5dd7070Spatrick SourceLocation(), SourceLocation(),
3020e5dd7070Spatrick &PP.getIdentifierTable().get("bad_alloc"),
3021e5dd7070Spatrick nullptr);
3022e5dd7070Spatrick getStdBadAlloc()->setImplicit(true);
3023*12c85518Srobert
3024*12c85518Srobert // The implicitly declared "std::bad_alloc" should live in global module
3025*12c85518Srobert // fragment.
3026*12c85518Srobert if (GlobalModuleFragment) {
3027*12c85518Srobert getStdBadAlloc()->setModuleOwnershipKind(
3028*12c85518Srobert Decl::ModuleOwnershipKind::ReachableWhenImported);
3029*12c85518Srobert getStdBadAlloc()->setLocalOwningModule(GlobalModuleFragment);
3030*12c85518Srobert }
3031e5dd7070Spatrick }
3032e5dd7070Spatrick if (!StdAlignValT && getLangOpts().AlignedAllocation) {
3033e5dd7070Spatrick // The "std::align_val_t" enum class has not yet been declared, so build it
3034e5dd7070Spatrick // implicitly.
3035e5dd7070Spatrick auto *AlignValT = EnumDecl::Create(
3036e5dd7070Spatrick Context, getOrCreateStdNamespace(), SourceLocation(), SourceLocation(),
3037e5dd7070Spatrick &PP.getIdentifierTable().get("align_val_t"), nullptr, true, true, true);
3038*12c85518Srobert
3039*12c85518Srobert // The implicitly declared "std::align_val_t" should live in global module
3040*12c85518Srobert // fragment.
3041*12c85518Srobert if (GlobalModuleFragment) {
3042*12c85518Srobert AlignValT->setModuleOwnershipKind(
3043*12c85518Srobert Decl::ModuleOwnershipKind::ReachableWhenImported);
3044*12c85518Srobert AlignValT->setLocalOwningModule(GlobalModuleFragment);
3045*12c85518Srobert }
3046*12c85518Srobert
3047e5dd7070Spatrick AlignValT->setIntegerType(Context.getSizeType());
3048e5dd7070Spatrick AlignValT->setPromotionType(Context.getSizeType());
3049e5dd7070Spatrick AlignValT->setImplicit(true);
3050*12c85518Srobert
3051e5dd7070Spatrick StdAlignValT = AlignValT;
3052e5dd7070Spatrick }
3053e5dd7070Spatrick
3054e5dd7070Spatrick GlobalNewDeleteDeclared = true;
3055e5dd7070Spatrick
3056e5dd7070Spatrick QualType VoidPtr = Context.getPointerType(Context.VoidTy);
3057e5dd7070Spatrick QualType SizeT = Context.getSizeType();
3058e5dd7070Spatrick
3059e5dd7070Spatrick auto DeclareGlobalAllocationFunctions = [&](OverloadedOperatorKind Kind,
3060e5dd7070Spatrick QualType Return, QualType Param) {
3061e5dd7070Spatrick llvm::SmallVector<QualType, 3> Params;
3062e5dd7070Spatrick Params.push_back(Param);
3063e5dd7070Spatrick
3064e5dd7070Spatrick // Create up to four variants of the function (sized/aligned).
3065e5dd7070Spatrick bool HasSizedVariant = getLangOpts().SizedDeallocation &&
3066e5dd7070Spatrick (Kind == OO_Delete || Kind == OO_Array_Delete);
3067e5dd7070Spatrick bool HasAlignedVariant = getLangOpts().AlignedAllocation;
3068e5dd7070Spatrick
3069e5dd7070Spatrick int NumSizeVariants = (HasSizedVariant ? 2 : 1);
3070e5dd7070Spatrick int NumAlignVariants = (HasAlignedVariant ? 2 : 1);
3071e5dd7070Spatrick for (int Sized = 0; Sized < NumSizeVariants; ++Sized) {
3072e5dd7070Spatrick if (Sized)
3073e5dd7070Spatrick Params.push_back(SizeT);
3074e5dd7070Spatrick
3075e5dd7070Spatrick for (int Aligned = 0; Aligned < NumAlignVariants; ++Aligned) {
3076e5dd7070Spatrick if (Aligned)
3077e5dd7070Spatrick Params.push_back(Context.getTypeDeclType(getStdAlignValT()));
3078e5dd7070Spatrick
3079e5dd7070Spatrick DeclareGlobalAllocationFunction(
3080e5dd7070Spatrick Context.DeclarationNames.getCXXOperatorName(Kind), Return, Params);
3081e5dd7070Spatrick
3082e5dd7070Spatrick if (Aligned)
3083e5dd7070Spatrick Params.pop_back();
3084e5dd7070Spatrick }
3085e5dd7070Spatrick }
3086e5dd7070Spatrick };
3087e5dd7070Spatrick
3088e5dd7070Spatrick DeclareGlobalAllocationFunctions(OO_New, VoidPtr, SizeT);
3089e5dd7070Spatrick DeclareGlobalAllocationFunctions(OO_Array_New, VoidPtr, SizeT);
3090e5dd7070Spatrick DeclareGlobalAllocationFunctions(OO_Delete, Context.VoidTy, VoidPtr);
3091e5dd7070Spatrick DeclareGlobalAllocationFunctions(OO_Array_Delete, Context.VoidTy, VoidPtr);
3092*12c85518Srobert
3093*12c85518Srobert if (getLangOpts().CPlusPlusModules && getCurrentModule())
3094*12c85518Srobert PopGlobalModuleFragment();
3095e5dd7070Spatrick }
3096e5dd7070Spatrick
3097e5dd7070Spatrick /// DeclareGlobalAllocationFunction - Declares a single implicit global
3098e5dd7070Spatrick /// allocation function if it doesn't already exist.
DeclareGlobalAllocationFunction(DeclarationName Name,QualType Return,ArrayRef<QualType> Params)3099e5dd7070Spatrick void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
3100e5dd7070Spatrick QualType Return,
3101e5dd7070Spatrick ArrayRef<QualType> Params) {
3102e5dd7070Spatrick DeclContext *GlobalCtx = Context.getTranslationUnitDecl();
3103e5dd7070Spatrick
3104e5dd7070Spatrick // Check if this function is already declared.
3105e5dd7070Spatrick DeclContext::lookup_result R = GlobalCtx->lookup(Name);
3106e5dd7070Spatrick for (DeclContext::lookup_iterator Alloc = R.begin(), AllocEnd = R.end();
3107e5dd7070Spatrick Alloc != AllocEnd; ++Alloc) {
3108e5dd7070Spatrick // Only look at non-template functions, as it is the predefined,
3109e5dd7070Spatrick // non-templated allocation function we are trying to declare here.
3110e5dd7070Spatrick if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*Alloc)) {
3111e5dd7070Spatrick if (Func->getNumParams() == Params.size()) {
3112e5dd7070Spatrick llvm::SmallVector<QualType, 3> FuncParams;
3113e5dd7070Spatrick for (auto *P : Func->parameters())
3114e5dd7070Spatrick FuncParams.push_back(
3115e5dd7070Spatrick Context.getCanonicalType(P->getType().getUnqualifiedType()));
3116*12c85518Srobert if (llvm::ArrayRef(FuncParams) == Params) {
3117e5dd7070Spatrick // Make the function visible to name lookup, even if we found it in
3118e5dd7070Spatrick // an unimported module. It either is an implicitly-declared global
3119e5dd7070Spatrick // allocation function, or is suppressing that function.
3120e5dd7070Spatrick Func->setVisibleDespiteOwningModule();
3121e5dd7070Spatrick return;
3122e5dd7070Spatrick }
3123e5dd7070Spatrick }
3124e5dd7070Spatrick }
3125e5dd7070Spatrick }
3126e5dd7070Spatrick
3127e5dd7070Spatrick FunctionProtoType::ExtProtoInfo EPI(Context.getDefaultCallingConvention(
3128e5dd7070Spatrick /*IsVariadic=*/false, /*IsCXXMethod=*/false, /*IsBuiltin=*/true));
3129e5dd7070Spatrick
3130e5dd7070Spatrick QualType BadAllocType;
3131e5dd7070Spatrick bool HasBadAllocExceptionSpec
3132e5dd7070Spatrick = (Name.getCXXOverloadedOperator() == OO_New ||
3133e5dd7070Spatrick Name.getCXXOverloadedOperator() == OO_Array_New);
3134e5dd7070Spatrick if (HasBadAllocExceptionSpec) {
3135e5dd7070Spatrick if (!getLangOpts().CPlusPlus11) {
3136e5dd7070Spatrick BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
3137e5dd7070Spatrick assert(StdBadAlloc && "Must have std::bad_alloc declared");
3138e5dd7070Spatrick EPI.ExceptionSpec.Type = EST_Dynamic;
3139*12c85518Srobert EPI.ExceptionSpec.Exceptions = llvm::ArrayRef(BadAllocType);
3140*12c85518Srobert }
3141*12c85518Srobert if (getLangOpts().NewInfallible) {
3142*12c85518Srobert EPI.ExceptionSpec.Type = EST_DynamicNone;
3143e5dd7070Spatrick }
3144e5dd7070Spatrick } else {
3145e5dd7070Spatrick EPI.ExceptionSpec =
3146e5dd7070Spatrick getLangOpts().CPlusPlus11 ? EST_BasicNoexcept : EST_DynamicNone;
3147e5dd7070Spatrick }
3148e5dd7070Spatrick
3149e5dd7070Spatrick auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) {
3150e5dd7070Spatrick QualType FnType = Context.getFunctionType(Return, Params, EPI);
3151e5dd7070Spatrick FunctionDecl *Alloc = FunctionDecl::Create(
3152*12c85518Srobert Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, FnType,
3153*12c85518Srobert /*TInfo=*/nullptr, SC_None, getCurFPFeatures().isFPConstrained(), false,
3154*12c85518Srobert true);
3155e5dd7070Spatrick Alloc->setImplicit();
3156e5dd7070Spatrick // Global allocation functions should always be visible.
3157e5dd7070Spatrick Alloc->setVisibleDespiteOwningModule();
3158e5dd7070Spatrick
3159*12c85518Srobert if (HasBadAllocExceptionSpec && getLangOpts().NewInfallible)
3160*12c85518Srobert Alloc->addAttr(
3161*12c85518Srobert ReturnsNonNullAttr::CreateImplicit(Context, Alloc->getLocation()));
3162*12c85518Srobert
3163*12c85518Srobert // C++ [basic.stc.dynamic.general]p2:
3164*12c85518Srobert // The library provides default definitions for the global allocation
3165*12c85518Srobert // and deallocation functions. Some global allocation and deallocation
3166*12c85518Srobert // functions are replaceable ([new.delete]); these are attached to the
3167*12c85518Srobert // global module ([module.unit]).
3168*12c85518Srobert //
3169*12c85518Srobert // In the language wording, these functions are attched to the global
3170*12c85518Srobert // module all the time. But in the implementation, the global module
3171*12c85518Srobert // is only meaningful when we're in a module unit. So here we attach
3172*12c85518Srobert // these allocation functions to global module conditionally.
3173*12c85518Srobert if (GlobalModuleFragment) {
3174*12c85518Srobert Alloc->setModuleOwnershipKind(
3175*12c85518Srobert Decl::ModuleOwnershipKind::ReachableWhenImported);
3176*12c85518Srobert Alloc->setLocalOwningModule(GlobalModuleFragment);
3177*12c85518Srobert }
3178*12c85518Srobert
3179e5dd7070Spatrick Alloc->addAttr(VisibilityAttr::CreateImplicit(
3180e5dd7070Spatrick Context, LangOpts.GlobalAllocationFunctionVisibilityHidden
3181e5dd7070Spatrick ? VisibilityAttr::Hidden
3182e5dd7070Spatrick : VisibilityAttr::Default));
3183e5dd7070Spatrick
3184e5dd7070Spatrick llvm::SmallVector<ParmVarDecl *, 3> ParamDecls;
3185e5dd7070Spatrick for (QualType T : Params) {
3186e5dd7070Spatrick ParamDecls.push_back(ParmVarDecl::Create(
3187e5dd7070Spatrick Context, Alloc, SourceLocation(), SourceLocation(), nullptr, T,
3188e5dd7070Spatrick /*TInfo=*/nullptr, SC_None, nullptr));
3189e5dd7070Spatrick ParamDecls.back()->setImplicit();
3190e5dd7070Spatrick }
3191e5dd7070Spatrick Alloc->setParams(ParamDecls);
3192e5dd7070Spatrick if (ExtraAttr)
3193e5dd7070Spatrick Alloc->addAttr(ExtraAttr);
3194ec727ea7Spatrick AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction(Alloc);
3195e5dd7070Spatrick Context.getTranslationUnitDecl()->addDecl(Alloc);
3196e5dd7070Spatrick IdResolver.tryAddTopLevelDecl(Alloc, Name);
3197e5dd7070Spatrick };
3198e5dd7070Spatrick
3199e5dd7070Spatrick if (!LangOpts.CUDA)
3200e5dd7070Spatrick CreateAllocationFunctionDecl(nullptr);
3201e5dd7070Spatrick else {
3202e5dd7070Spatrick // Host and device get their own declaration so each can be
3203e5dd7070Spatrick // defined or re-declared independently.
3204e5dd7070Spatrick CreateAllocationFunctionDecl(CUDAHostAttr::CreateImplicit(Context));
3205e5dd7070Spatrick CreateAllocationFunctionDecl(CUDADeviceAttr::CreateImplicit(Context));
3206e5dd7070Spatrick }
3207e5dd7070Spatrick }
3208e5dd7070Spatrick
FindUsualDeallocationFunction(SourceLocation StartLoc,bool CanProvideSize,bool Overaligned,DeclarationName Name)3209e5dd7070Spatrick FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc,
3210e5dd7070Spatrick bool CanProvideSize,
3211e5dd7070Spatrick bool Overaligned,
3212e5dd7070Spatrick DeclarationName Name) {
3213e5dd7070Spatrick DeclareGlobalNewDelete();
3214e5dd7070Spatrick
3215e5dd7070Spatrick LookupResult FoundDelete(*this, Name, StartLoc, LookupOrdinaryName);
3216e5dd7070Spatrick LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl());
3217e5dd7070Spatrick
3218e5dd7070Spatrick // FIXME: It's possible for this to result in ambiguity, through a
3219e5dd7070Spatrick // user-declared variadic operator delete or the enable_if attribute. We
3220e5dd7070Spatrick // should probably not consider those cases to be usual deallocation
3221e5dd7070Spatrick // functions. But for now we just make an arbitrary choice in that case.
3222e5dd7070Spatrick auto Result = resolveDeallocationOverload(*this, FoundDelete, CanProvideSize,
3223e5dd7070Spatrick Overaligned);
3224e5dd7070Spatrick assert(Result.FD && "operator delete missing from global scope?");
3225e5dd7070Spatrick return Result.FD;
3226e5dd7070Spatrick }
3227e5dd7070Spatrick
FindDeallocationFunctionForDestructor(SourceLocation Loc,CXXRecordDecl * RD)3228e5dd7070Spatrick FunctionDecl *Sema::FindDeallocationFunctionForDestructor(SourceLocation Loc,
3229e5dd7070Spatrick CXXRecordDecl *RD) {
3230e5dd7070Spatrick DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Delete);
3231e5dd7070Spatrick
3232e5dd7070Spatrick FunctionDecl *OperatorDelete = nullptr;
3233e5dd7070Spatrick if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
3234e5dd7070Spatrick return nullptr;
3235e5dd7070Spatrick if (OperatorDelete)
3236e5dd7070Spatrick return OperatorDelete;
3237e5dd7070Spatrick
3238e5dd7070Spatrick // If there's no class-specific operator delete, look up the global
3239e5dd7070Spatrick // non-array delete.
3240e5dd7070Spatrick return FindUsualDeallocationFunction(
3241e5dd7070Spatrick Loc, true, hasNewExtendedAlignment(*this, Context.getRecordType(RD)),
3242e5dd7070Spatrick Name);
3243e5dd7070Spatrick }
3244e5dd7070Spatrick
FindDeallocationFunction(SourceLocation StartLoc,CXXRecordDecl * RD,DeclarationName Name,FunctionDecl * & Operator,bool Diagnose,bool WantSize,bool WantAligned)3245e5dd7070Spatrick bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
3246e5dd7070Spatrick DeclarationName Name,
3247*12c85518Srobert FunctionDecl *&Operator, bool Diagnose,
3248*12c85518Srobert bool WantSize, bool WantAligned) {
3249e5dd7070Spatrick LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName);
3250e5dd7070Spatrick // Try to find operator delete/operator delete[] in class scope.
3251e5dd7070Spatrick LookupQualifiedName(Found, RD);
3252e5dd7070Spatrick
3253e5dd7070Spatrick if (Found.isAmbiguous())
3254e5dd7070Spatrick return true;
3255e5dd7070Spatrick
3256e5dd7070Spatrick Found.suppressDiagnostics();
3257e5dd7070Spatrick
3258*12c85518Srobert bool Overaligned =
3259*12c85518Srobert WantAligned || hasNewExtendedAlignment(*this, Context.getRecordType(RD));
3260e5dd7070Spatrick
3261e5dd7070Spatrick // C++17 [expr.delete]p10:
3262e5dd7070Spatrick // If the deallocation functions have class scope, the one without a
3263e5dd7070Spatrick // parameter of type std::size_t is selected.
3264e5dd7070Spatrick llvm::SmallVector<UsualDeallocFnInfo, 4> Matches;
3265*12c85518Srobert resolveDeallocationOverload(*this, Found, /*WantSize*/ WantSize,
3266e5dd7070Spatrick /*WantAlign*/ Overaligned, &Matches);
3267e5dd7070Spatrick
3268e5dd7070Spatrick // If we could find an overload, use it.
3269e5dd7070Spatrick if (Matches.size() == 1) {
3270e5dd7070Spatrick Operator = cast<CXXMethodDecl>(Matches[0].FD);
3271e5dd7070Spatrick
3272e5dd7070Spatrick // FIXME: DiagnoseUseOfDecl?
3273e5dd7070Spatrick if (Operator->isDeleted()) {
3274e5dd7070Spatrick if (Diagnose) {
3275e5dd7070Spatrick Diag(StartLoc, diag::err_deleted_function_use);
3276e5dd7070Spatrick NoteDeletedFunction(Operator);
3277e5dd7070Spatrick }
3278e5dd7070Spatrick return true;
3279e5dd7070Spatrick }
3280e5dd7070Spatrick
3281e5dd7070Spatrick if (CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
3282e5dd7070Spatrick Matches[0].Found, Diagnose) == AR_inaccessible)
3283e5dd7070Spatrick return true;
3284e5dd7070Spatrick
3285e5dd7070Spatrick return false;
3286e5dd7070Spatrick }
3287e5dd7070Spatrick
3288e5dd7070Spatrick // We found multiple suitable operators; complain about the ambiguity.
3289e5dd7070Spatrick // FIXME: The standard doesn't say to do this; it appears that the intent
3290e5dd7070Spatrick // is that this should never happen.
3291e5dd7070Spatrick if (!Matches.empty()) {
3292e5dd7070Spatrick if (Diagnose) {
3293e5dd7070Spatrick Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
3294e5dd7070Spatrick << Name << RD;
3295e5dd7070Spatrick for (auto &Match : Matches)
3296e5dd7070Spatrick Diag(Match.FD->getLocation(), diag::note_member_declared_here) << Name;
3297e5dd7070Spatrick }
3298e5dd7070Spatrick return true;
3299e5dd7070Spatrick }
3300e5dd7070Spatrick
3301e5dd7070Spatrick // We did find operator delete/operator delete[] declarations, but
3302e5dd7070Spatrick // none of them were suitable.
3303e5dd7070Spatrick if (!Found.empty()) {
3304e5dd7070Spatrick if (Diagnose) {
3305e5dd7070Spatrick Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
3306e5dd7070Spatrick << Name << RD;
3307e5dd7070Spatrick
3308e5dd7070Spatrick for (NamedDecl *D : Found)
3309e5dd7070Spatrick Diag(D->getUnderlyingDecl()->getLocation(),
3310e5dd7070Spatrick diag::note_member_declared_here) << Name;
3311e5dd7070Spatrick }
3312e5dd7070Spatrick return true;
3313e5dd7070Spatrick }
3314e5dd7070Spatrick
3315e5dd7070Spatrick Operator = nullptr;
3316e5dd7070Spatrick return false;
3317e5dd7070Spatrick }
3318e5dd7070Spatrick
3319e5dd7070Spatrick namespace {
3320e5dd7070Spatrick /// Checks whether delete-expression, and new-expression used for
3321e5dd7070Spatrick /// initializing deletee have the same array form.
3322e5dd7070Spatrick class MismatchingNewDeleteDetector {
3323e5dd7070Spatrick public:
3324e5dd7070Spatrick enum MismatchResult {
3325e5dd7070Spatrick /// Indicates that there is no mismatch or a mismatch cannot be proven.
3326e5dd7070Spatrick NoMismatch,
3327e5dd7070Spatrick /// Indicates that variable is initialized with mismatching form of \a new.
3328e5dd7070Spatrick VarInitMismatches,
3329e5dd7070Spatrick /// Indicates that member is initialized with mismatching form of \a new.
3330e5dd7070Spatrick MemberInitMismatches,
3331e5dd7070Spatrick /// Indicates that 1 or more constructors' definitions could not been
3332e5dd7070Spatrick /// analyzed, and they will be checked again at the end of translation unit.
3333e5dd7070Spatrick AnalyzeLater
3334e5dd7070Spatrick };
3335e5dd7070Spatrick
3336e5dd7070Spatrick /// \param EndOfTU True, if this is the final analysis at the end of
3337e5dd7070Spatrick /// translation unit. False, if this is the initial analysis at the point
3338e5dd7070Spatrick /// delete-expression was encountered.
MismatchingNewDeleteDetector(bool EndOfTU)3339e5dd7070Spatrick explicit MismatchingNewDeleteDetector(bool EndOfTU)
3340e5dd7070Spatrick : Field(nullptr), IsArrayForm(false), EndOfTU(EndOfTU),
3341e5dd7070Spatrick HasUndefinedConstructors(false) {}
3342e5dd7070Spatrick
3343e5dd7070Spatrick /// Checks whether pointee of a delete-expression is initialized with
3344e5dd7070Spatrick /// matching form of new-expression.
3345e5dd7070Spatrick ///
3346e5dd7070Spatrick /// If return value is \c VarInitMismatches or \c MemberInitMismatches at the
3347e5dd7070Spatrick /// point where delete-expression is encountered, then a warning will be
3348e5dd7070Spatrick /// issued immediately. If return value is \c AnalyzeLater at the point where
3349e5dd7070Spatrick /// delete-expression is seen, then member will be analyzed at the end of
3350e5dd7070Spatrick /// translation unit. \c AnalyzeLater is returned iff at least one constructor
3351e5dd7070Spatrick /// couldn't be analyzed. If at least one constructor initializes the member
3352e5dd7070Spatrick /// with matching type of new, the return value is \c NoMismatch.
3353e5dd7070Spatrick MismatchResult analyzeDeleteExpr(const CXXDeleteExpr *DE);
3354e5dd7070Spatrick /// Analyzes a class member.
3355e5dd7070Spatrick /// \param Field Class member to analyze.
3356e5dd7070Spatrick /// \param DeleteWasArrayForm Array form-ness of the delete-expression used
3357e5dd7070Spatrick /// for deleting the \p Field.
3358e5dd7070Spatrick MismatchResult analyzeField(FieldDecl *Field, bool DeleteWasArrayForm);
3359e5dd7070Spatrick FieldDecl *Field;
3360e5dd7070Spatrick /// List of mismatching new-expressions used for initialization of the pointee
3361e5dd7070Spatrick llvm::SmallVector<const CXXNewExpr *, 4> NewExprs;
3362e5dd7070Spatrick /// Indicates whether delete-expression was in array form.
3363e5dd7070Spatrick bool IsArrayForm;
3364e5dd7070Spatrick
3365e5dd7070Spatrick private:
3366e5dd7070Spatrick const bool EndOfTU;
3367e5dd7070Spatrick /// Indicates that there is at least one constructor without body.
3368e5dd7070Spatrick bool HasUndefinedConstructors;
3369e5dd7070Spatrick /// Returns \c CXXNewExpr from given initialization expression.
3370e5dd7070Spatrick /// \param E Expression used for initializing pointee in delete-expression.
3371e5dd7070Spatrick /// E can be a single-element \c InitListExpr consisting of new-expression.
3372e5dd7070Spatrick const CXXNewExpr *getNewExprFromInitListOrExpr(const Expr *E);
3373e5dd7070Spatrick /// Returns whether member is initialized with mismatching form of
3374e5dd7070Spatrick /// \c new either by the member initializer or in-class initialization.
3375e5dd7070Spatrick ///
3376e5dd7070Spatrick /// If bodies of all constructors are not visible at the end of translation
3377e5dd7070Spatrick /// unit or at least one constructor initializes member with the matching
3378e5dd7070Spatrick /// form of \c new, mismatch cannot be proven, and this function will return
3379e5dd7070Spatrick /// \c NoMismatch.
3380e5dd7070Spatrick MismatchResult analyzeMemberExpr(const MemberExpr *ME);
3381e5dd7070Spatrick /// Returns whether variable is initialized with mismatching form of
3382e5dd7070Spatrick /// \c new.
3383e5dd7070Spatrick ///
3384e5dd7070Spatrick /// If variable is initialized with matching form of \c new or variable is not
3385e5dd7070Spatrick /// initialized with a \c new expression, this function will return true.
3386e5dd7070Spatrick /// If variable is initialized with mismatching form of \c new, returns false.
3387e5dd7070Spatrick /// \param D Variable to analyze.
3388e5dd7070Spatrick bool hasMatchingVarInit(const DeclRefExpr *D);
3389e5dd7070Spatrick /// Checks whether the constructor initializes pointee with mismatching
3390e5dd7070Spatrick /// form of \c new.
3391e5dd7070Spatrick ///
3392e5dd7070Spatrick /// Returns true, if member is initialized with matching form of \c new in
3393e5dd7070Spatrick /// member initializer list. Returns false, if member is initialized with the
3394e5dd7070Spatrick /// matching form of \c new in this constructor's initializer or given
3395e5dd7070Spatrick /// constructor isn't defined at the point where delete-expression is seen, or
3396e5dd7070Spatrick /// member isn't initialized by the constructor.
3397e5dd7070Spatrick bool hasMatchingNewInCtor(const CXXConstructorDecl *CD);
3398e5dd7070Spatrick /// Checks whether member is initialized with matching form of
3399e5dd7070Spatrick /// \c new in member initializer list.
3400e5dd7070Spatrick bool hasMatchingNewInCtorInit(const CXXCtorInitializer *CI);
3401e5dd7070Spatrick /// Checks whether member is initialized with mismatching form of \c new by
3402e5dd7070Spatrick /// in-class initializer.
3403e5dd7070Spatrick MismatchResult analyzeInClassInitializer();
3404e5dd7070Spatrick };
3405e5dd7070Spatrick }
3406e5dd7070Spatrick
3407e5dd7070Spatrick MismatchingNewDeleteDetector::MismatchResult
analyzeDeleteExpr(const CXXDeleteExpr * DE)3408e5dd7070Spatrick MismatchingNewDeleteDetector::analyzeDeleteExpr(const CXXDeleteExpr *DE) {
3409e5dd7070Spatrick NewExprs.clear();
3410e5dd7070Spatrick assert(DE && "Expected delete-expression");
3411e5dd7070Spatrick IsArrayForm = DE->isArrayForm();
3412e5dd7070Spatrick const Expr *E = DE->getArgument()->IgnoreParenImpCasts();
3413e5dd7070Spatrick if (const MemberExpr *ME = dyn_cast<const MemberExpr>(E)) {
3414e5dd7070Spatrick return analyzeMemberExpr(ME);
3415e5dd7070Spatrick } else if (const DeclRefExpr *D = dyn_cast<const DeclRefExpr>(E)) {
3416e5dd7070Spatrick if (!hasMatchingVarInit(D))
3417e5dd7070Spatrick return VarInitMismatches;
3418e5dd7070Spatrick }
3419e5dd7070Spatrick return NoMismatch;
3420e5dd7070Spatrick }
3421e5dd7070Spatrick
3422e5dd7070Spatrick const CXXNewExpr *
getNewExprFromInitListOrExpr(const Expr * E)3423e5dd7070Spatrick MismatchingNewDeleteDetector::getNewExprFromInitListOrExpr(const Expr *E) {
3424e5dd7070Spatrick assert(E != nullptr && "Expected a valid initializer expression");
3425e5dd7070Spatrick E = E->IgnoreParenImpCasts();
3426e5dd7070Spatrick if (const InitListExpr *ILE = dyn_cast<const InitListExpr>(E)) {
3427e5dd7070Spatrick if (ILE->getNumInits() == 1)
3428e5dd7070Spatrick E = dyn_cast<const CXXNewExpr>(ILE->getInit(0)->IgnoreParenImpCasts());
3429e5dd7070Spatrick }
3430e5dd7070Spatrick
3431e5dd7070Spatrick return dyn_cast_or_null<const CXXNewExpr>(E);
3432e5dd7070Spatrick }
3433e5dd7070Spatrick
hasMatchingNewInCtorInit(const CXXCtorInitializer * CI)3434e5dd7070Spatrick bool MismatchingNewDeleteDetector::hasMatchingNewInCtorInit(
3435e5dd7070Spatrick const CXXCtorInitializer *CI) {
3436e5dd7070Spatrick const CXXNewExpr *NE = nullptr;
3437e5dd7070Spatrick if (Field == CI->getMember() &&
3438e5dd7070Spatrick (NE = getNewExprFromInitListOrExpr(CI->getInit()))) {
3439e5dd7070Spatrick if (NE->isArray() == IsArrayForm)
3440e5dd7070Spatrick return true;
3441e5dd7070Spatrick else
3442e5dd7070Spatrick NewExprs.push_back(NE);
3443e5dd7070Spatrick }
3444e5dd7070Spatrick return false;
3445e5dd7070Spatrick }
3446e5dd7070Spatrick
hasMatchingNewInCtor(const CXXConstructorDecl * CD)3447e5dd7070Spatrick bool MismatchingNewDeleteDetector::hasMatchingNewInCtor(
3448e5dd7070Spatrick const CXXConstructorDecl *CD) {
3449e5dd7070Spatrick if (CD->isImplicit())
3450e5dd7070Spatrick return false;
3451e5dd7070Spatrick const FunctionDecl *Definition = CD;
3452e5dd7070Spatrick if (!CD->isThisDeclarationADefinition() && !CD->isDefined(Definition)) {
3453e5dd7070Spatrick HasUndefinedConstructors = true;
3454e5dd7070Spatrick return EndOfTU;
3455e5dd7070Spatrick }
3456e5dd7070Spatrick for (const auto *CI : cast<const CXXConstructorDecl>(Definition)->inits()) {
3457e5dd7070Spatrick if (hasMatchingNewInCtorInit(CI))
3458e5dd7070Spatrick return true;
3459e5dd7070Spatrick }
3460e5dd7070Spatrick return false;
3461e5dd7070Spatrick }
3462e5dd7070Spatrick
3463e5dd7070Spatrick MismatchingNewDeleteDetector::MismatchResult
analyzeInClassInitializer()3464e5dd7070Spatrick MismatchingNewDeleteDetector::analyzeInClassInitializer() {
3465e5dd7070Spatrick assert(Field != nullptr && "This should be called only for members");
3466e5dd7070Spatrick const Expr *InitExpr = Field->getInClassInitializer();
3467e5dd7070Spatrick if (!InitExpr)
3468e5dd7070Spatrick return EndOfTU ? NoMismatch : AnalyzeLater;
3469e5dd7070Spatrick if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) {
3470e5dd7070Spatrick if (NE->isArray() != IsArrayForm) {
3471e5dd7070Spatrick NewExprs.push_back(NE);
3472e5dd7070Spatrick return MemberInitMismatches;
3473e5dd7070Spatrick }
3474e5dd7070Spatrick }
3475e5dd7070Spatrick return NoMismatch;
3476e5dd7070Spatrick }
3477e5dd7070Spatrick
3478e5dd7070Spatrick MismatchingNewDeleteDetector::MismatchResult
analyzeField(FieldDecl * Field,bool DeleteWasArrayForm)3479e5dd7070Spatrick MismatchingNewDeleteDetector::analyzeField(FieldDecl *Field,
3480e5dd7070Spatrick bool DeleteWasArrayForm) {
3481e5dd7070Spatrick assert(Field != nullptr && "Analysis requires a valid class member.");
3482e5dd7070Spatrick this->Field = Field;
3483e5dd7070Spatrick IsArrayForm = DeleteWasArrayForm;
3484e5dd7070Spatrick const CXXRecordDecl *RD = cast<const CXXRecordDecl>(Field->getParent());
3485e5dd7070Spatrick for (const auto *CD : RD->ctors()) {
3486e5dd7070Spatrick if (hasMatchingNewInCtor(CD))
3487e5dd7070Spatrick return NoMismatch;
3488e5dd7070Spatrick }
3489e5dd7070Spatrick if (HasUndefinedConstructors)
3490e5dd7070Spatrick return EndOfTU ? NoMismatch : AnalyzeLater;
3491e5dd7070Spatrick if (!NewExprs.empty())
3492e5dd7070Spatrick return MemberInitMismatches;
3493e5dd7070Spatrick return Field->hasInClassInitializer() ? analyzeInClassInitializer()
3494e5dd7070Spatrick : NoMismatch;
3495e5dd7070Spatrick }
3496e5dd7070Spatrick
3497e5dd7070Spatrick MismatchingNewDeleteDetector::MismatchResult
analyzeMemberExpr(const MemberExpr * ME)3498e5dd7070Spatrick MismatchingNewDeleteDetector::analyzeMemberExpr(const MemberExpr *ME) {
3499e5dd7070Spatrick assert(ME != nullptr && "Expected a member expression");
3500e5dd7070Spatrick if (FieldDecl *F = dyn_cast<FieldDecl>(ME->getMemberDecl()))
3501e5dd7070Spatrick return analyzeField(F, IsArrayForm);
3502e5dd7070Spatrick return NoMismatch;
3503e5dd7070Spatrick }
3504e5dd7070Spatrick
hasMatchingVarInit(const DeclRefExpr * D)3505e5dd7070Spatrick bool MismatchingNewDeleteDetector::hasMatchingVarInit(const DeclRefExpr *D) {
3506e5dd7070Spatrick const CXXNewExpr *NE = nullptr;
3507e5dd7070Spatrick if (const VarDecl *VD = dyn_cast<const VarDecl>(D->getDecl())) {
3508e5dd7070Spatrick if (VD->hasInit() && (NE = getNewExprFromInitListOrExpr(VD->getInit())) &&
3509e5dd7070Spatrick NE->isArray() != IsArrayForm) {
3510e5dd7070Spatrick NewExprs.push_back(NE);
3511e5dd7070Spatrick }
3512e5dd7070Spatrick }
3513e5dd7070Spatrick return NewExprs.empty();
3514e5dd7070Spatrick }
3515e5dd7070Spatrick
3516e5dd7070Spatrick static void
DiagnoseMismatchedNewDelete(Sema & SemaRef,SourceLocation DeleteLoc,const MismatchingNewDeleteDetector & Detector)3517e5dd7070Spatrick DiagnoseMismatchedNewDelete(Sema &SemaRef, SourceLocation DeleteLoc,
3518e5dd7070Spatrick const MismatchingNewDeleteDetector &Detector) {
3519e5dd7070Spatrick SourceLocation EndOfDelete = SemaRef.getLocForEndOfToken(DeleteLoc);
3520e5dd7070Spatrick FixItHint H;
3521e5dd7070Spatrick if (!Detector.IsArrayForm)
3522e5dd7070Spatrick H = FixItHint::CreateInsertion(EndOfDelete, "[]");
3523e5dd7070Spatrick else {
3524e5dd7070Spatrick SourceLocation RSquare = Lexer::findLocationAfterToken(
3525e5dd7070Spatrick DeleteLoc, tok::l_square, SemaRef.getSourceManager(),
3526e5dd7070Spatrick SemaRef.getLangOpts(), true);
3527e5dd7070Spatrick if (RSquare.isValid())
3528e5dd7070Spatrick H = FixItHint::CreateRemoval(SourceRange(EndOfDelete, RSquare));
3529e5dd7070Spatrick }
3530e5dd7070Spatrick SemaRef.Diag(DeleteLoc, diag::warn_mismatched_delete_new)
3531e5dd7070Spatrick << Detector.IsArrayForm << H;
3532e5dd7070Spatrick
3533e5dd7070Spatrick for (const auto *NE : Detector.NewExprs)
3534e5dd7070Spatrick SemaRef.Diag(NE->getExprLoc(), diag::note_allocated_here)
3535e5dd7070Spatrick << Detector.IsArrayForm;
3536e5dd7070Spatrick }
3537e5dd7070Spatrick
AnalyzeDeleteExprMismatch(const CXXDeleteExpr * DE)3538e5dd7070Spatrick void Sema::AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE) {
3539e5dd7070Spatrick if (Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation()))
3540e5dd7070Spatrick return;
3541e5dd7070Spatrick MismatchingNewDeleteDetector Detector(/*EndOfTU=*/false);
3542e5dd7070Spatrick switch (Detector.analyzeDeleteExpr(DE)) {
3543e5dd7070Spatrick case MismatchingNewDeleteDetector::VarInitMismatches:
3544e5dd7070Spatrick case MismatchingNewDeleteDetector::MemberInitMismatches: {
3545e5dd7070Spatrick DiagnoseMismatchedNewDelete(*this, DE->getBeginLoc(), Detector);
3546e5dd7070Spatrick break;
3547e5dd7070Spatrick }
3548e5dd7070Spatrick case MismatchingNewDeleteDetector::AnalyzeLater: {
3549e5dd7070Spatrick DeleteExprs[Detector.Field].push_back(
3550e5dd7070Spatrick std::make_pair(DE->getBeginLoc(), DE->isArrayForm()));
3551e5dd7070Spatrick break;
3552e5dd7070Spatrick }
3553e5dd7070Spatrick case MismatchingNewDeleteDetector::NoMismatch:
3554e5dd7070Spatrick break;
3555e5dd7070Spatrick }
3556e5dd7070Spatrick }
3557e5dd7070Spatrick
AnalyzeDeleteExprMismatch(FieldDecl * Field,SourceLocation DeleteLoc,bool DeleteWasArrayForm)3558e5dd7070Spatrick void Sema::AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,
3559e5dd7070Spatrick bool DeleteWasArrayForm) {
3560e5dd7070Spatrick MismatchingNewDeleteDetector Detector(/*EndOfTU=*/true);
3561e5dd7070Spatrick switch (Detector.analyzeField(Field, DeleteWasArrayForm)) {
3562e5dd7070Spatrick case MismatchingNewDeleteDetector::VarInitMismatches:
3563e5dd7070Spatrick llvm_unreachable("This analysis should have been done for class members.");
3564e5dd7070Spatrick case MismatchingNewDeleteDetector::AnalyzeLater:
3565e5dd7070Spatrick llvm_unreachable("Analysis cannot be postponed any point beyond end of "
3566e5dd7070Spatrick "translation unit.");
3567e5dd7070Spatrick case MismatchingNewDeleteDetector::MemberInitMismatches:
3568e5dd7070Spatrick DiagnoseMismatchedNewDelete(*this, DeleteLoc, Detector);
3569e5dd7070Spatrick break;
3570e5dd7070Spatrick case MismatchingNewDeleteDetector::NoMismatch:
3571e5dd7070Spatrick break;
3572e5dd7070Spatrick }
3573e5dd7070Spatrick }
3574e5dd7070Spatrick
3575e5dd7070Spatrick /// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
3576e5dd7070Spatrick /// @code ::delete ptr; @endcode
3577e5dd7070Spatrick /// or
3578e5dd7070Spatrick /// @code delete [] ptr; @endcode
3579e5dd7070Spatrick ExprResult
ActOnCXXDelete(SourceLocation StartLoc,bool UseGlobal,bool ArrayForm,Expr * ExE)3580e5dd7070Spatrick Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
3581e5dd7070Spatrick bool ArrayForm, Expr *ExE) {
3582e5dd7070Spatrick // C++ [expr.delete]p1:
3583e5dd7070Spatrick // The operand shall have a pointer type, or a class type having a single
3584e5dd7070Spatrick // non-explicit conversion function to a pointer type. The result has type
3585e5dd7070Spatrick // void.
3586e5dd7070Spatrick //
3587e5dd7070Spatrick // DR599 amends "pointer type" to "pointer to object type" in both cases.
3588e5dd7070Spatrick
3589e5dd7070Spatrick ExprResult Ex = ExE;
3590e5dd7070Spatrick FunctionDecl *OperatorDelete = nullptr;
3591e5dd7070Spatrick bool ArrayFormAsWritten = ArrayForm;
3592e5dd7070Spatrick bool UsualArrayDeleteWantsSize = false;
3593e5dd7070Spatrick
3594e5dd7070Spatrick if (!Ex.get()->isTypeDependent()) {
3595e5dd7070Spatrick // Perform lvalue-to-rvalue cast, if needed.
3596e5dd7070Spatrick Ex = DefaultLvalueConversion(Ex.get());
3597e5dd7070Spatrick if (Ex.isInvalid())
3598e5dd7070Spatrick return ExprError();
3599e5dd7070Spatrick
3600e5dd7070Spatrick QualType Type = Ex.get()->getType();
3601e5dd7070Spatrick
3602e5dd7070Spatrick class DeleteConverter : public ContextualImplicitConverter {
3603e5dd7070Spatrick public:
3604e5dd7070Spatrick DeleteConverter() : ContextualImplicitConverter(false, true) {}
3605e5dd7070Spatrick
3606e5dd7070Spatrick bool match(QualType ConvType) override {
3607e5dd7070Spatrick // FIXME: If we have an operator T* and an operator void*, we must pick
3608e5dd7070Spatrick // the operator T*.
3609e5dd7070Spatrick if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
3610e5dd7070Spatrick if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType())
3611e5dd7070Spatrick return true;
3612e5dd7070Spatrick return false;
3613e5dd7070Spatrick }
3614e5dd7070Spatrick
3615e5dd7070Spatrick SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc,
3616e5dd7070Spatrick QualType T) override {
3617e5dd7070Spatrick return S.Diag(Loc, diag::err_delete_operand) << T;
3618e5dd7070Spatrick }
3619e5dd7070Spatrick
3620e5dd7070Spatrick SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
3621e5dd7070Spatrick QualType T) override {
3622e5dd7070Spatrick return S.Diag(Loc, diag::err_delete_incomplete_class_type) << T;
3623e5dd7070Spatrick }
3624e5dd7070Spatrick
3625e5dd7070Spatrick SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
3626e5dd7070Spatrick QualType T,
3627e5dd7070Spatrick QualType ConvTy) override {
3628e5dd7070Spatrick return S.Diag(Loc, diag::err_delete_explicit_conversion) << T << ConvTy;
3629e5dd7070Spatrick }
3630e5dd7070Spatrick
3631e5dd7070Spatrick SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
3632e5dd7070Spatrick QualType ConvTy) override {
3633e5dd7070Spatrick return S.Diag(Conv->getLocation(), diag::note_delete_conversion)
3634e5dd7070Spatrick << ConvTy;
3635e5dd7070Spatrick }
3636e5dd7070Spatrick
3637e5dd7070Spatrick SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
3638e5dd7070Spatrick QualType T) override {
3639e5dd7070Spatrick return S.Diag(Loc, diag::err_ambiguous_delete_operand) << T;
3640e5dd7070Spatrick }
3641e5dd7070Spatrick
3642e5dd7070Spatrick SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
3643e5dd7070Spatrick QualType ConvTy) override {
3644e5dd7070Spatrick return S.Diag(Conv->getLocation(), diag::note_delete_conversion)
3645e5dd7070Spatrick << ConvTy;
3646e5dd7070Spatrick }
3647e5dd7070Spatrick
3648e5dd7070Spatrick SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc,
3649e5dd7070Spatrick QualType T,
3650e5dd7070Spatrick QualType ConvTy) override {
3651e5dd7070Spatrick llvm_unreachable("conversion functions are permitted");
3652e5dd7070Spatrick }
3653e5dd7070Spatrick } Converter;
3654e5dd7070Spatrick
3655e5dd7070Spatrick Ex = PerformContextualImplicitConversion(StartLoc, Ex.get(), Converter);
3656e5dd7070Spatrick if (Ex.isInvalid())
3657e5dd7070Spatrick return ExprError();
3658e5dd7070Spatrick Type = Ex.get()->getType();
3659e5dd7070Spatrick if (!Converter.match(Type))
3660e5dd7070Spatrick // FIXME: PerformContextualImplicitConversion should return ExprError
3661e5dd7070Spatrick // itself in this case.
3662e5dd7070Spatrick return ExprError();
3663e5dd7070Spatrick
3664e5dd7070Spatrick QualType Pointee = Type->castAs<PointerType>()->getPointeeType();
3665e5dd7070Spatrick QualType PointeeElem = Context.getBaseElementType(Pointee);
3666e5dd7070Spatrick
3667e5dd7070Spatrick if (Pointee.getAddressSpace() != LangAS::Default &&
3668e5dd7070Spatrick !getLangOpts().OpenCLCPlusPlus)
3669e5dd7070Spatrick return Diag(Ex.get()->getBeginLoc(),
3670e5dd7070Spatrick diag::err_address_space_qualified_delete)
3671e5dd7070Spatrick << Pointee.getUnqualifiedType()
3672e5dd7070Spatrick << Pointee.getQualifiers().getAddressSpaceAttributePrintValue();
3673e5dd7070Spatrick
3674e5dd7070Spatrick CXXRecordDecl *PointeeRD = nullptr;
3675e5dd7070Spatrick if (Pointee->isVoidType() && !isSFINAEContext()) {
3676e5dd7070Spatrick // The C++ standard bans deleting a pointer to a non-object type, which
3677e5dd7070Spatrick // effectively bans deletion of "void*". However, most compilers support
3678e5dd7070Spatrick // this, so we treat it as a warning unless we're in a SFINAE context.
3679e5dd7070Spatrick Diag(StartLoc, diag::ext_delete_void_ptr_operand)
3680e5dd7070Spatrick << Type << Ex.get()->getSourceRange();
3681ec727ea7Spatrick } else if (Pointee->isFunctionType() || Pointee->isVoidType() ||
3682ec727ea7Spatrick Pointee->isSizelessType()) {
3683e5dd7070Spatrick return ExprError(Diag(StartLoc, diag::err_delete_operand)
3684e5dd7070Spatrick << Type << Ex.get()->getSourceRange());
3685e5dd7070Spatrick } else if (!Pointee->isDependentType()) {
3686e5dd7070Spatrick // FIXME: This can result in errors if the definition was imported from a
3687e5dd7070Spatrick // module but is hidden.
3688e5dd7070Spatrick if (!RequireCompleteType(StartLoc, Pointee,
3689e5dd7070Spatrick diag::warn_delete_incomplete, Ex.get())) {
3690e5dd7070Spatrick if (const RecordType *RT = PointeeElem->getAs<RecordType>())
3691e5dd7070Spatrick PointeeRD = cast<CXXRecordDecl>(RT->getDecl());
3692e5dd7070Spatrick }
3693e5dd7070Spatrick }
3694e5dd7070Spatrick
3695e5dd7070Spatrick if (Pointee->isArrayType() && !ArrayForm) {
3696e5dd7070Spatrick Diag(StartLoc, diag::warn_delete_array_type)
3697e5dd7070Spatrick << Type << Ex.get()->getSourceRange()
3698e5dd7070Spatrick << FixItHint::CreateInsertion(getLocForEndOfToken(StartLoc), "[]");
3699e5dd7070Spatrick ArrayForm = true;
3700e5dd7070Spatrick }
3701e5dd7070Spatrick
3702e5dd7070Spatrick DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
3703e5dd7070Spatrick ArrayForm ? OO_Array_Delete : OO_Delete);
3704e5dd7070Spatrick
3705e5dd7070Spatrick if (PointeeRD) {
3706e5dd7070Spatrick if (!UseGlobal &&
3707e5dd7070Spatrick FindDeallocationFunction(StartLoc, PointeeRD, DeleteName,
3708e5dd7070Spatrick OperatorDelete))
3709e5dd7070Spatrick return ExprError();
3710e5dd7070Spatrick
3711e5dd7070Spatrick // If we're allocating an array of records, check whether the
3712e5dd7070Spatrick // usual operator delete[] has a size_t parameter.
3713e5dd7070Spatrick if (ArrayForm) {
3714e5dd7070Spatrick // If the user specifically asked to use the global allocator,
3715e5dd7070Spatrick // we'll need to do the lookup into the class.
3716e5dd7070Spatrick if (UseGlobal)
3717e5dd7070Spatrick UsualArrayDeleteWantsSize =
3718e5dd7070Spatrick doesUsualArrayDeleteWantSize(*this, StartLoc, PointeeElem);
3719e5dd7070Spatrick
3720e5dd7070Spatrick // Otherwise, the usual operator delete[] should be the
3721e5dd7070Spatrick // function we just found.
3722e5dd7070Spatrick else if (OperatorDelete && isa<CXXMethodDecl>(OperatorDelete))
3723e5dd7070Spatrick UsualArrayDeleteWantsSize =
3724e5dd7070Spatrick UsualDeallocFnInfo(*this,
3725e5dd7070Spatrick DeclAccessPair::make(OperatorDelete, AS_public))
3726e5dd7070Spatrick .HasSizeT;
3727e5dd7070Spatrick }
3728e5dd7070Spatrick
3729e5dd7070Spatrick if (!PointeeRD->hasIrrelevantDestructor())
3730e5dd7070Spatrick if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
3731e5dd7070Spatrick MarkFunctionReferenced(StartLoc,
3732e5dd7070Spatrick const_cast<CXXDestructorDecl*>(Dtor));
3733e5dd7070Spatrick if (DiagnoseUseOfDecl(Dtor, StartLoc))
3734e5dd7070Spatrick return ExprError();
3735e5dd7070Spatrick }
3736e5dd7070Spatrick
3737e5dd7070Spatrick CheckVirtualDtorCall(PointeeRD->getDestructor(), StartLoc,
3738e5dd7070Spatrick /*IsDelete=*/true, /*CallCanBeVirtual=*/true,
3739e5dd7070Spatrick /*WarnOnNonAbstractTypes=*/!ArrayForm,
3740e5dd7070Spatrick SourceLocation());
3741e5dd7070Spatrick }
3742e5dd7070Spatrick
3743e5dd7070Spatrick if (!OperatorDelete) {
3744e5dd7070Spatrick if (getLangOpts().OpenCLCPlusPlus) {
3745e5dd7070Spatrick Diag(StartLoc, diag::err_openclcxx_not_supported) << "default delete";
3746e5dd7070Spatrick return ExprError();
3747e5dd7070Spatrick }
3748e5dd7070Spatrick
3749e5dd7070Spatrick bool IsComplete = isCompleteType(StartLoc, Pointee);
3750e5dd7070Spatrick bool CanProvideSize =
3751e5dd7070Spatrick IsComplete && (!ArrayForm || UsualArrayDeleteWantsSize ||
3752e5dd7070Spatrick Pointee.isDestructedType());
3753e5dd7070Spatrick bool Overaligned = hasNewExtendedAlignment(*this, Pointee);
3754e5dd7070Spatrick
3755e5dd7070Spatrick // Look for a global declaration.
3756e5dd7070Spatrick OperatorDelete = FindUsualDeallocationFunction(StartLoc, CanProvideSize,
3757e5dd7070Spatrick Overaligned, DeleteName);
3758e5dd7070Spatrick }
3759e5dd7070Spatrick
3760e5dd7070Spatrick MarkFunctionReferenced(StartLoc, OperatorDelete);
3761e5dd7070Spatrick
3762e5dd7070Spatrick // Check access and ambiguity of destructor if we're going to call it.
3763e5dd7070Spatrick // Note that this is required even for a virtual delete.
3764e5dd7070Spatrick bool IsVirtualDelete = false;
3765e5dd7070Spatrick if (PointeeRD) {
3766e5dd7070Spatrick if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
3767e5dd7070Spatrick CheckDestructorAccess(Ex.get()->getExprLoc(), Dtor,
3768e5dd7070Spatrick PDiag(diag::err_access_dtor) << PointeeElem);
3769e5dd7070Spatrick IsVirtualDelete = Dtor->isVirtual();
3770e5dd7070Spatrick }
3771e5dd7070Spatrick }
3772e5dd7070Spatrick
3773e5dd7070Spatrick DiagnoseUseOfDecl(OperatorDelete, StartLoc);
3774e5dd7070Spatrick
3775e5dd7070Spatrick // Convert the operand to the type of the first parameter of operator
3776e5dd7070Spatrick // delete. This is only necessary if we selected a destroying operator
3777e5dd7070Spatrick // delete that we are going to call (non-virtually); converting to void*
3778e5dd7070Spatrick // is trivial and left to AST consumers to handle.
3779e5dd7070Spatrick QualType ParamType = OperatorDelete->getParamDecl(0)->getType();
3780e5dd7070Spatrick if (!IsVirtualDelete && !ParamType->getPointeeType()->isVoidType()) {
3781e5dd7070Spatrick Qualifiers Qs = Pointee.getQualifiers();
3782e5dd7070Spatrick if (Qs.hasCVRQualifiers()) {
3783e5dd7070Spatrick // Qualifiers are irrelevant to this conversion; we're only looking
3784e5dd7070Spatrick // for access and ambiguity.
3785e5dd7070Spatrick Qs.removeCVRQualifiers();
3786e5dd7070Spatrick QualType Unqual = Context.getPointerType(
3787e5dd7070Spatrick Context.getQualifiedType(Pointee.getUnqualifiedType(), Qs));
3788e5dd7070Spatrick Ex = ImpCastExprToType(Ex.get(), Unqual, CK_NoOp);
3789e5dd7070Spatrick }
3790e5dd7070Spatrick Ex = PerformImplicitConversion(Ex.get(), ParamType, AA_Passing);
3791e5dd7070Spatrick if (Ex.isInvalid())
3792e5dd7070Spatrick return ExprError();
3793e5dd7070Spatrick }
3794e5dd7070Spatrick }
3795e5dd7070Spatrick
3796e5dd7070Spatrick CXXDeleteExpr *Result = new (Context) CXXDeleteExpr(
3797e5dd7070Spatrick Context.VoidTy, UseGlobal, ArrayForm, ArrayFormAsWritten,
3798e5dd7070Spatrick UsualArrayDeleteWantsSize, OperatorDelete, Ex.get(), StartLoc);
3799e5dd7070Spatrick AnalyzeDeleteExprMismatch(Result);
3800e5dd7070Spatrick return Result;
3801e5dd7070Spatrick }
3802e5dd7070Spatrick
resolveBuiltinNewDeleteOverload(Sema & S,CallExpr * TheCall,bool IsDelete,FunctionDecl * & Operator)3803e5dd7070Spatrick static bool resolveBuiltinNewDeleteOverload(Sema &S, CallExpr *TheCall,
3804e5dd7070Spatrick bool IsDelete,
3805e5dd7070Spatrick FunctionDecl *&Operator) {
3806e5dd7070Spatrick
3807e5dd7070Spatrick DeclarationName NewName = S.Context.DeclarationNames.getCXXOperatorName(
3808e5dd7070Spatrick IsDelete ? OO_Delete : OO_New);
3809e5dd7070Spatrick
3810e5dd7070Spatrick LookupResult R(S, NewName, TheCall->getBeginLoc(), Sema::LookupOrdinaryName);
3811e5dd7070Spatrick S.LookupQualifiedName(R, S.Context.getTranslationUnitDecl());
3812e5dd7070Spatrick assert(!R.empty() && "implicitly declared allocation functions not found");
3813e5dd7070Spatrick assert(!R.isAmbiguous() && "global allocation functions are ambiguous");
3814e5dd7070Spatrick
3815e5dd7070Spatrick // We do our own custom access checks below.
3816e5dd7070Spatrick R.suppressDiagnostics();
3817e5dd7070Spatrick
3818*12c85518Srobert SmallVector<Expr *, 8> Args(TheCall->arguments());
3819e5dd7070Spatrick OverloadCandidateSet Candidates(R.getNameLoc(),
3820e5dd7070Spatrick OverloadCandidateSet::CSK_Normal);
3821e5dd7070Spatrick for (LookupResult::iterator FnOvl = R.begin(), FnOvlEnd = R.end();
3822e5dd7070Spatrick FnOvl != FnOvlEnd; ++FnOvl) {
3823e5dd7070Spatrick // Even member operator new/delete are implicitly treated as
3824e5dd7070Spatrick // static, so don't use AddMemberCandidate.
3825e5dd7070Spatrick NamedDecl *D = (*FnOvl)->getUnderlyingDecl();
3826e5dd7070Spatrick
3827e5dd7070Spatrick if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl>(D)) {
3828e5dd7070Spatrick S.AddTemplateOverloadCandidate(FnTemplate, FnOvl.getPair(),
3829e5dd7070Spatrick /*ExplicitTemplateArgs=*/nullptr, Args,
3830e5dd7070Spatrick Candidates,
3831e5dd7070Spatrick /*SuppressUserConversions=*/false);
3832e5dd7070Spatrick continue;
3833e5dd7070Spatrick }
3834e5dd7070Spatrick
3835e5dd7070Spatrick FunctionDecl *Fn = cast<FunctionDecl>(D);
3836e5dd7070Spatrick S.AddOverloadCandidate(Fn, FnOvl.getPair(), Args, Candidates,
3837e5dd7070Spatrick /*SuppressUserConversions=*/false);
3838e5dd7070Spatrick }
3839e5dd7070Spatrick
3840e5dd7070Spatrick SourceRange Range = TheCall->getSourceRange();
3841e5dd7070Spatrick
3842e5dd7070Spatrick // Do the resolution.
3843e5dd7070Spatrick OverloadCandidateSet::iterator Best;
3844e5dd7070Spatrick switch (Candidates.BestViableFunction(S, R.getNameLoc(), Best)) {
3845e5dd7070Spatrick case OR_Success: {
3846e5dd7070Spatrick // Got one!
3847e5dd7070Spatrick FunctionDecl *FnDecl = Best->Function;
3848e5dd7070Spatrick assert(R.getNamingClass() == nullptr &&
3849e5dd7070Spatrick "class members should not be considered");
3850e5dd7070Spatrick
3851e5dd7070Spatrick if (!FnDecl->isReplaceableGlobalAllocationFunction()) {
3852e5dd7070Spatrick S.Diag(R.getNameLoc(), diag::err_builtin_operator_new_delete_not_usual)
3853e5dd7070Spatrick << (IsDelete ? 1 : 0) << Range;
3854e5dd7070Spatrick S.Diag(FnDecl->getLocation(), diag::note_non_usual_function_declared_here)
3855e5dd7070Spatrick << R.getLookupName() << FnDecl->getSourceRange();
3856e5dd7070Spatrick return true;
3857e5dd7070Spatrick }
3858e5dd7070Spatrick
3859e5dd7070Spatrick Operator = FnDecl;
3860e5dd7070Spatrick return false;
3861e5dd7070Spatrick }
3862e5dd7070Spatrick
3863e5dd7070Spatrick case OR_No_Viable_Function:
3864e5dd7070Spatrick Candidates.NoteCandidates(
3865e5dd7070Spatrick PartialDiagnosticAt(R.getNameLoc(),
3866e5dd7070Spatrick S.PDiag(diag::err_ovl_no_viable_function_in_call)
3867e5dd7070Spatrick << R.getLookupName() << Range),
3868e5dd7070Spatrick S, OCD_AllCandidates, Args);
3869e5dd7070Spatrick return true;
3870e5dd7070Spatrick
3871e5dd7070Spatrick case OR_Ambiguous:
3872e5dd7070Spatrick Candidates.NoteCandidates(
3873e5dd7070Spatrick PartialDiagnosticAt(R.getNameLoc(),
3874e5dd7070Spatrick S.PDiag(diag::err_ovl_ambiguous_call)
3875e5dd7070Spatrick << R.getLookupName() << Range),
3876e5dd7070Spatrick S, OCD_AmbiguousCandidates, Args);
3877e5dd7070Spatrick return true;
3878e5dd7070Spatrick
3879e5dd7070Spatrick case OR_Deleted: {
3880e5dd7070Spatrick Candidates.NoteCandidates(
3881e5dd7070Spatrick PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_deleted_call)
3882e5dd7070Spatrick << R.getLookupName() << Range),
3883e5dd7070Spatrick S, OCD_AllCandidates, Args);
3884e5dd7070Spatrick return true;
3885e5dd7070Spatrick }
3886e5dd7070Spatrick }
3887e5dd7070Spatrick llvm_unreachable("Unreachable, bad result from BestViableFunction");
3888e5dd7070Spatrick }
3889e5dd7070Spatrick
3890e5dd7070Spatrick ExprResult
SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult,bool IsDelete)3891e5dd7070Spatrick Sema::SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult,
3892e5dd7070Spatrick bool IsDelete) {
3893e5dd7070Spatrick CallExpr *TheCall = cast<CallExpr>(TheCallResult.get());
3894e5dd7070Spatrick if (!getLangOpts().CPlusPlus) {
3895e5dd7070Spatrick Diag(TheCall->getExprLoc(), diag::err_builtin_requires_language)
3896e5dd7070Spatrick << (IsDelete ? "__builtin_operator_delete" : "__builtin_operator_new")
3897e5dd7070Spatrick << "C++";
3898e5dd7070Spatrick return ExprError();
3899e5dd7070Spatrick }
3900e5dd7070Spatrick // CodeGen assumes it can find the global new and delete to call,
3901e5dd7070Spatrick // so ensure that they are declared.
3902e5dd7070Spatrick DeclareGlobalNewDelete();
3903e5dd7070Spatrick
3904e5dd7070Spatrick FunctionDecl *OperatorNewOrDelete = nullptr;
3905e5dd7070Spatrick if (resolveBuiltinNewDeleteOverload(*this, TheCall, IsDelete,
3906e5dd7070Spatrick OperatorNewOrDelete))
3907e5dd7070Spatrick return ExprError();
3908e5dd7070Spatrick assert(OperatorNewOrDelete && "should be found");
3909e5dd7070Spatrick
3910e5dd7070Spatrick DiagnoseUseOfDecl(OperatorNewOrDelete, TheCall->getExprLoc());
3911e5dd7070Spatrick MarkFunctionReferenced(TheCall->getExprLoc(), OperatorNewOrDelete);
3912e5dd7070Spatrick
3913e5dd7070Spatrick TheCall->setType(OperatorNewOrDelete->getReturnType());
3914e5dd7070Spatrick for (unsigned i = 0; i != TheCall->getNumArgs(); ++i) {
3915e5dd7070Spatrick QualType ParamTy = OperatorNewOrDelete->getParamDecl(i)->getType();
3916e5dd7070Spatrick InitializedEntity Entity =
3917e5dd7070Spatrick InitializedEntity::InitializeParameter(Context, ParamTy, false);
3918e5dd7070Spatrick ExprResult Arg = PerformCopyInitialization(
3919e5dd7070Spatrick Entity, TheCall->getArg(i)->getBeginLoc(), TheCall->getArg(i));
3920e5dd7070Spatrick if (Arg.isInvalid())
3921e5dd7070Spatrick return ExprError();
3922e5dd7070Spatrick TheCall->setArg(i, Arg.get());
3923e5dd7070Spatrick }
3924e5dd7070Spatrick auto Callee = dyn_cast<ImplicitCastExpr>(TheCall->getCallee());
3925e5dd7070Spatrick assert(Callee && Callee->getCastKind() == CK_BuiltinFnToFnPtr &&
3926e5dd7070Spatrick "Callee expected to be implicit cast to a builtin function pointer");
3927e5dd7070Spatrick Callee->setType(OperatorNewOrDelete->getType());
3928e5dd7070Spatrick
3929e5dd7070Spatrick return TheCallResult;
3930e5dd7070Spatrick }
3931e5dd7070Spatrick
CheckVirtualDtorCall(CXXDestructorDecl * dtor,SourceLocation Loc,bool IsDelete,bool CallCanBeVirtual,bool WarnOnNonAbstractTypes,SourceLocation DtorLoc)3932e5dd7070Spatrick void Sema::CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc,
3933e5dd7070Spatrick bool IsDelete, bool CallCanBeVirtual,
3934e5dd7070Spatrick bool WarnOnNonAbstractTypes,
3935e5dd7070Spatrick SourceLocation DtorLoc) {
3936e5dd7070Spatrick if (!dtor || dtor->isVirtual() || !CallCanBeVirtual || isUnevaluatedContext())
3937e5dd7070Spatrick return;
3938e5dd7070Spatrick
3939e5dd7070Spatrick // C++ [expr.delete]p3:
3940e5dd7070Spatrick // In the first alternative (delete object), if the static type of the
3941e5dd7070Spatrick // object to be deleted is different from its dynamic type, the static
3942e5dd7070Spatrick // type shall be a base class of the dynamic type of the object to be
3943e5dd7070Spatrick // deleted and the static type shall have a virtual destructor or the
3944e5dd7070Spatrick // behavior is undefined.
3945e5dd7070Spatrick //
3946e5dd7070Spatrick const CXXRecordDecl *PointeeRD = dtor->getParent();
3947e5dd7070Spatrick // Note: a final class cannot be derived from, no issue there
3948e5dd7070Spatrick if (!PointeeRD->isPolymorphic() || PointeeRD->hasAttr<FinalAttr>())
3949e5dd7070Spatrick return;
3950e5dd7070Spatrick
3951e5dd7070Spatrick // If the superclass is in a system header, there's nothing that can be done.
3952e5dd7070Spatrick // The `delete` (where we emit the warning) can be in a system header,
3953e5dd7070Spatrick // what matters for this warning is where the deleted type is defined.
3954e5dd7070Spatrick if (getSourceManager().isInSystemHeader(PointeeRD->getLocation()))
3955e5dd7070Spatrick return;
3956e5dd7070Spatrick
3957e5dd7070Spatrick QualType ClassType = dtor->getThisType()->getPointeeType();
3958e5dd7070Spatrick if (PointeeRD->isAbstract()) {
3959e5dd7070Spatrick // If the class is abstract, we warn by default, because we're
3960e5dd7070Spatrick // sure the code has undefined behavior.
3961e5dd7070Spatrick Diag(Loc, diag::warn_delete_abstract_non_virtual_dtor) << (IsDelete ? 0 : 1)
3962e5dd7070Spatrick << ClassType;
3963e5dd7070Spatrick } else if (WarnOnNonAbstractTypes) {
3964e5dd7070Spatrick // Otherwise, if this is not an array delete, it's a bit suspect,
3965e5dd7070Spatrick // but not necessarily wrong.
3966e5dd7070Spatrick Diag(Loc, diag::warn_delete_non_virtual_dtor) << (IsDelete ? 0 : 1)
3967e5dd7070Spatrick << ClassType;
3968e5dd7070Spatrick }
3969e5dd7070Spatrick if (!IsDelete) {
3970e5dd7070Spatrick std::string TypeStr;
3971e5dd7070Spatrick ClassType.getAsStringInternal(TypeStr, getPrintingPolicy());
3972e5dd7070Spatrick Diag(DtorLoc, diag::note_delete_non_virtual)
3973e5dd7070Spatrick << FixItHint::CreateInsertion(DtorLoc, TypeStr + "::");
3974e5dd7070Spatrick }
3975e5dd7070Spatrick }
3976e5dd7070Spatrick
ActOnConditionVariable(Decl * ConditionVar,SourceLocation StmtLoc,ConditionKind CK)3977e5dd7070Spatrick Sema::ConditionResult Sema::ActOnConditionVariable(Decl *ConditionVar,
3978e5dd7070Spatrick SourceLocation StmtLoc,
3979e5dd7070Spatrick ConditionKind CK) {
3980e5dd7070Spatrick ExprResult E =
3981e5dd7070Spatrick CheckConditionVariable(cast<VarDecl>(ConditionVar), StmtLoc, CK);
3982e5dd7070Spatrick if (E.isInvalid())
3983e5dd7070Spatrick return ConditionError();
3984e5dd7070Spatrick return ConditionResult(*this, ConditionVar, MakeFullExpr(E.get(), StmtLoc),
3985e5dd7070Spatrick CK == ConditionKind::ConstexprIf);
3986e5dd7070Spatrick }
3987e5dd7070Spatrick
3988e5dd7070Spatrick /// Check the use of the given variable as a C++ condition in an if,
3989e5dd7070Spatrick /// while, do-while, or switch statement.
CheckConditionVariable(VarDecl * ConditionVar,SourceLocation StmtLoc,ConditionKind CK)3990e5dd7070Spatrick ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
3991e5dd7070Spatrick SourceLocation StmtLoc,
3992e5dd7070Spatrick ConditionKind CK) {
3993e5dd7070Spatrick if (ConditionVar->isInvalidDecl())
3994e5dd7070Spatrick return ExprError();
3995e5dd7070Spatrick
3996e5dd7070Spatrick QualType T = ConditionVar->getType();
3997e5dd7070Spatrick
3998e5dd7070Spatrick // C++ [stmt.select]p2:
3999e5dd7070Spatrick // The declarator shall not specify a function or an array.
4000e5dd7070Spatrick if (T->isFunctionType())
4001e5dd7070Spatrick return ExprError(Diag(ConditionVar->getLocation(),
4002e5dd7070Spatrick diag::err_invalid_use_of_function_type)
4003e5dd7070Spatrick << ConditionVar->getSourceRange());
4004e5dd7070Spatrick else if (T->isArrayType())
4005e5dd7070Spatrick return ExprError(Diag(ConditionVar->getLocation(),
4006e5dd7070Spatrick diag::err_invalid_use_of_array_type)
4007e5dd7070Spatrick << ConditionVar->getSourceRange());
4008e5dd7070Spatrick
4009e5dd7070Spatrick ExprResult Condition = BuildDeclRefExpr(
4010e5dd7070Spatrick ConditionVar, ConditionVar->getType().getNonReferenceType(), VK_LValue,
4011e5dd7070Spatrick ConditionVar->getLocation());
4012e5dd7070Spatrick
4013e5dd7070Spatrick switch (CK) {
4014e5dd7070Spatrick case ConditionKind::Boolean:
4015e5dd7070Spatrick return CheckBooleanCondition(StmtLoc, Condition.get());
4016e5dd7070Spatrick
4017e5dd7070Spatrick case ConditionKind::ConstexprIf:
4018e5dd7070Spatrick return CheckBooleanCondition(StmtLoc, Condition.get(), true);
4019e5dd7070Spatrick
4020e5dd7070Spatrick case ConditionKind::Switch:
4021e5dd7070Spatrick return CheckSwitchCondition(StmtLoc, Condition.get());
4022e5dd7070Spatrick }
4023e5dd7070Spatrick
4024e5dd7070Spatrick llvm_unreachable("unexpected condition kind");
4025e5dd7070Spatrick }
4026e5dd7070Spatrick
4027e5dd7070Spatrick /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.
CheckCXXBooleanCondition(Expr * CondExpr,bool IsConstexpr)4028e5dd7070Spatrick ExprResult Sema::CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr) {
4029a9ac8606Spatrick // C++11 6.4p4:
4030e5dd7070Spatrick // The value of a condition that is an initialized declaration in a statement
4031e5dd7070Spatrick // other than a switch statement is the value of the declared variable
4032e5dd7070Spatrick // implicitly converted to type bool. If that conversion is ill-formed, the
4033e5dd7070Spatrick // program is ill-formed.
4034e5dd7070Spatrick // The value of a condition that is an expression is the value of the
4035e5dd7070Spatrick // expression, implicitly converted to bool.
4036e5dd7070Spatrick //
4037a9ac8606Spatrick // C++2b 8.5.2p2
4038a9ac8606Spatrick // If the if statement is of the form if constexpr, the value of the condition
4039a9ac8606Spatrick // is contextually converted to bool and the converted expression shall be
4040a9ac8606Spatrick // a constant expression.
4041a9ac8606Spatrick //
4042a9ac8606Spatrick
4043a9ac8606Spatrick ExprResult E = PerformContextuallyConvertToBool(CondExpr);
4044a9ac8606Spatrick if (!IsConstexpr || E.isInvalid() || E.get()->isValueDependent())
4045a9ac8606Spatrick return E;
4046a9ac8606Spatrick
4047e5dd7070Spatrick // FIXME: Return this value to the caller so they don't need to recompute it.
4048a9ac8606Spatrick llvm::APSInt Cond;
4049a9ac8606Spatrick E = VerifyIntegerConstantExpression(
4050a9ac8606Spatrick E.get(), &Cond,
4051a9ac8606Spatrick diag::err_constexpr_if_condition_expression_is_not_constant);
4052a9ac8606Spatrick return E;
4053e5dd7070Spatrick }
4054e5dd7070Spatrick
4055e5dd7070Spatrick /// Helper function to determine whether this is the (deprecated) C++
4056e5dd7070Spatrick /// conversion from a string literal to a pointer to non-const char or
4057e5dd7070Spatrick /// non-const wchar_t (for narrow and wide string literals,
4058e5dd7070Spatrick /// respectively).
4059e5dd7070Spatrick bool
IsStringLiteralToNonConstPointerConversion(Expr * From,QualType ToType)4060e5dd7070Spatrick Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {
4061e5dd7070Spatrick // Look inside the implicit cast, if it exists.
4062e5dd7070Spatrick if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(From))
4063e5dd7070Spatrick From = Cast->getSubExpr();
4064e5dd7070Spatrick
4065e5dd7070Spatrick // A string literal (2.13.4) that is not a wide string literal can
4066e5dd7070Spatrick // be converted to an rvalue of type "pointer to char"; a wide
4067e5dd7070Spatrick // string literal can be converted to an rvalue of type "pointer
4068e5dd7070Spatrick // to wchar_t" (C++ 4.2p2).
4069e5dd7070Spatrick if (StringLiteral *StrLit = dyn_cast<StringLiteral>(From->IgnoreParens()))
4070e5dd7070Spatrick if (const PointerType *ToPtrType = ToType->getAs<PointerType>())
4071e5dd7070Spatrick if (const BuiltinType *ToPointeeType
4072e5dd7070Spatrick = ToPtrType->getPointeeType()->getAs<BuiltinType>()) {
4073e5dd7070Spatrick // This conversion is considered only when there is an
4074e5dd7070Spatrick // explicit appropriate pointer target type (C++ 4.2p2).
4075e5dd7070Spatrick if (!ToPtrType->getPointeeType().hasQualifiers()) {
4076e5dd7070Spatrick switch (StrLit->getKind()) {
4077e5dd7070Spatrick case StringLiteral::UTF8:
4078e5dd7070Spatrick case StringLiteral::UTF16:
4079e5dd7070Spatrick case StringLiteral::UTF32:
4080e5dd7070Spatrick // We don't allow UTF literals to be implicitly converted
4081e5dd7070Spatrick break;
4082*12c85518Srobert case StringLiteral::Ordinary:
4083e5dd7070Spatrick return (ToPointeeType->getKind() == BuiltinType::Char_U ||
4084e5dd7070Spatrick ToPointeeType->getKind() == BuiltinType::Char_S);
4085e5dd7070Spatrick case StringLiteral::Wide:
4086e5dd7070Spatrick return Context.typesAreCompatible(Context.getWideCharType(),
4087e5dd7070Spatrick QualType(ToPointeeType, 0));
4088e5dd7070Spatrick }
4089e5dd7070Spatrick }
4090e5dd7070Spatrick }
4091e5dd7070Spatrick
4092e5dd7070Spatrick return false;
4093e5dd7070Spatrick }
4094e5dd7070Spatrick
BuildCXXCastArgument(Sema & S,SourceLocation CastLoc,QualType Ty,CastKind Kind,CXXMethodDecl * Method,DeclAccessPair FoundDecl,bool HadMultipleCandidates,Expr * From)4095e5dd7070Spatrick static ExprResult BuildCXXCastArgument(Sema &S,
4096e5dd7070Spatrick SourceLocation CastLoc,
4097e5dd7070Spatrick QualType Ty,
4098e5dd7070Spatrick CastKind Kind,
4099e5dd7070Spatrick CXXMethodDecl *Method,
4100e5dd7070Spatrick DeclAccessPair FoundDecl,
4101e5dd7070Spatrick bool HadMultipleCandidates,
4102e5dd7070Spatrick Expr *From) {
4103e5dd7070Spatrick switch (Kind) {
4104e5dd7070Spatrick default: llvm_unreachable("Unhandled cast kind!");
4105e5dd7070Spatrick case CK_ConstructorConversion: {
4106e5dd7070Spatrick CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Method);
4107e5dd7070Spatrick SmallVector<Expr*, 8> ConstructorArgs;
4108e5dd7070Spatrick
4109e5dd7070Spatrick if (S.RequireNonAbstractType(CastLoc, Ty,
4110e5dd7070Spatrick diag::err_allocation_of_abstract_type))
4111e5dd7070Spatrick return ExprError();
4112e5dd7070Spatrick
4113a9ac8606Spatrick if (S.CompleteConstructorCall(Constructor, Ty, From, CastLoc,
4114a9ac8606Spatrick ConstructorArgs))
4115e5dd7070Spatrick return ExprError();
4116e5dd7070Spatrick
4117e5dd7070Spatrick S.CheckConstructorAccess(CastLoc, Constructor, FoundDecl,
4118e5dd7070Spatrick InitializedEntity::InitializeTemporary(Ty));
4119e5dd7070Spatrick if (S.DiagnoseUseOfDecl(Method, CastLoc))
4120e5dd7070Spatrick return ExprError();
4121e5dd7070Spatrick
4122e5dd7070Spatrick ExprResult Result = S.BuildCXXConstructExpr(
4123e5dd7070Spatrick CastLoc, Ty, FoundDecl, cast<CXXConstructorDecl>(Method),
4124e5dd7070Spatrick ConstructorArgs, HadMultipleCandidates,
4125e5dd7070Spatrick /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
4126e5dd7070Spatrick CXXConstructExpr::CK_Complete, SourceRange());
4127e5dd7070Spatrick if (Result.isInvalid())
4128e5dd7070Spatrick return ExprError();
4129e5dd7070Spatrick
4130e5dd7070Spatrick return S.MaybeBindToTemporary(Result.getAs<Expr>());
4131e5dd7070Spatrick }
4132e5dd7070Spatrick
4133e5dd7070Spatrick case CK_UserDefinedConversion: {
4134e5dd7070Spatrick assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
4135e5dd7070Spatrick
4136e5dd7070Spatrick S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl);
4137e5dd7070Spatrick if (S.DiagnoseUseOfDecl(Method, CastLoc))
4138e5dd7070Spatrick return ExprError();
4139e5dd7070Spatrick
4140e5dd7070Spatrick // Create an implicit call expr that calls it.
4141e5dd7070Spatrick CXXConversionDecl *Conv = cast<CXXConversionDecl>(Method);
4142e5dd7070Spatrick ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Conv,
4143e5dd7070Spatrick HadMultipleCandidates);
4144e5dd7070Spatrick if (Result.isInvalid())
4145e5dd7070Spatrick return ExprError();
4146e5dd7070Spatrick // Record usage of conversion in an implicit cast.
4147e5dd7070Spatrick Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(),
4148e5dd7070Spatrick CK_UserDefinedConversion, Result.get(),
4149a9ac8606Spatrick nullptr, Result.get()->getValueKind(),
4150a9ac8606Spatrick S.CurFPFeatureOverrides());
4151e5dd7070Spatrick
4152e5dd7070Spatrick return S.MaybeBindToTemporary(Result.get());
4153e5dd7070Spatrick }
4154e5dd7070Spatrick }
4155e5dd7070Spatrick }
4156e5dd7070Spatrick
4157e5dd7070Spatrick /// PerformImplicitConversion - Perform an implicit conversion of the
4158e5dd7070Spatrick /// expression From to the type ToType using the pre-computed implicit
4159e5dd7070Spatrick /// conversion sequence ICS. Returns the converted
4160e5dd7070Spatrick /// expression. Action is the kind of conversion we're performing,
4161e5dd7070Spatrick /// used in the error message.
4162e5dd7070Spatrick ExprResult
PerformImplicitConversion(Expr * From,QualType ToType,const ImplicitConversionSequence & ICS,AssignmentAction Action,CheckedConversionKind CCK)4163e5dd7070Spatrick Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4164e5dd7070Spatrick const ImplicitConversionSequence &ICS,
4165e5dd7070Spatrick AssignmentAction Action,
4166e5dd7070Spatrick CheckedConversionKind CCK) {
4167e5dd7070Spatrick // C++ [over.match.oper]p7: [...] operands of class type are converted [...]
4168e5dd7070Spatrick if (CCK == CCK_ForBuiltinOverloadedOp && !From->getType()->isRecordType())
4169e5dd7070Spatrick return From;
4170e5dd7070Spatrick
4171e5dd7070Spatrick switch (ICS.getKind()) {
4172e5dd7070Spatrick case ImplicitConversionSequence::StandardConversion: {
4173e5dd7070Spatrick ExprResult Res = PerformImplicitConversion(From, ToType, ICS.Standard,
4174e5dd7070Spatrick Action, CCK);
4175e5dd7070Spatrick if (Res.isInvalid())
4176e5dd7070Spatrick return ExprError();
4177e5dd7070Spatrick From = Res.get();
4178e5dd7070Spatrick break;
4179e5dd7070Spatrick }
4180e5dd7070Spatrick
4181e5dd7070Spatrick case ImplicitConversionSequence::UserDefinedConversion: {
4182e5dd7070Spatrick
4183e5dd7070Spatrick FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
4184e5dd7070Spatrick CastKind CastKind;
4185e5dd7070Spatrick QualType BeforeToType;
4186e5dd7070Spatrick assert(FD && "no conversion function for user-defined conversion seq");
4187e5dd7070Spatrick if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) {
4188e5dd7070Spatrick CastKind = CK_UserDefinedConversion;
4189e5dd7070Spatrick
4190e5dd7070Spatrick // If the user-defined conversion is specified by a conversion function,
4191e5dd7070Spatrick // the initial standard conversion sequence converts the source type to
4192e5dd7070Spatrick // the implicit object parameter of the conversion function.
4193e5dd7070Spatrick BeforeToType = Context.getTagDeclType(Conv->getParent());
4194e5dd7070Spatrick } else {
4195e5dd7070Spatrick const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(FD);
4196e5dd7070Spatrick CastKind = CK_ConstructorConversion;
4197e5dd7070Spatrick // Do no conversion if dealing with ... for the first conversion.
4198e5dd7070Spatrick if (!ICS.UserDefined.EllipsisConversion) {
4199e5dd7070Spatrick // If the user-defined conversion is specified by a constructor, the
4200e5dd7070Spatrick // initial standard conversion sequence converts the source type to
4201e5dd7070Spatrick // the type required by the argument of the constructor
4202e5dd7070Spatrick BeforeToType = Ctor->getParamDecl(0)->getType().getNonReferenceType();
4203e5dd7070Spatrick }
4204e5dd7070Spatrick }
4205e5dd7070Spatrick // Watch out for ellipsis conversion.
4206e5dd7070Spatrick if (!ICS.UserDefined.EllipsisConversion) {
4207e5dd7070Spatrick ExprResult Res =
4208e5dd7070Spatrick PerformImplicitConversion(From, BeforeToType,
4209e5dd7070Spatrick ICS.UserDefined.Before, AA_Converting,
4210e5dd7070Spatrick CCK);
4211e5dd7070Spatrick if (Res.isInvalid())
4212e5dd7070Spatrick return ExprError();
4213e5dd7070Spatrick From = Res.get();
4214e5dd7070Spatrick }
4215e5dd7070Spatrick
4216e5dd7070Spatrick ExprResult CastArg = BuildCXXCastArgument(
4217e5dd7070Spatrick *this, From->getBeginLoc(), ToType.getNonReferenceType(), CastKind,
4218e5dd7070Spatrick cast<CXXMethodDecl>(FD), ICS.UserDefined.FoundConversionFunction,
4219e5dd7070Spatrick ICS.UserDefined.HadMultipleCandidates, From);
4220e5dd7070Spatrick
4221e5dd7070Spatrick if (CastArg.isInvalid())
4222e5dd7070Spatrick return ExprError();
4223e5dd7070Spatrick
4224e5dd7070Spatrick From = CastArg.get();
4225e5dd7070Spatrick
4226e5dd7070Spatrick // C++ [over.match.oper]p7:
4227e5dd7070Spatrick // [...] the second standard conversion sequence of a user-defined
4228e5dd7070Spatrick // conversion sequence is not applied.
4229e5dd7070Spatrick if (CCK == CCK_ForBuiltinOverloadedOp)
4230e5dd7070Spatrick return From;
4231e5dd7070Spatrick
4232e5dd7070Spatrick return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
4233e5dd7070Spatrick AA_Converting, CCK);
4234e5dd7070Spatrick }
4235e5dd7070Spatrick
4236e5dd7070Spatrick case ImplicitConversionSequence::AmbiguousConversion:
4237e5dd7070Spatrick ICS.DiagnoseAmbiguousConversion(*this, From->getExprLoc(),
4238e5dd7070Spatrick PDiag(diag::err_typecheck_ambiguous_condition)
4239e5dd7070Spatrick << From->getSourceRange());
4240e5dd7070Spatrick return ExprError();
4241e5dd7070Spatrick
4242e5dd7070Spatrick case ImplicitConversionSequence::EllipsisConversion:
4243*12c85518Srobert case ImplicitConversionSequence::StaticObjectArgumentConversion:
4244*12c85518Srobert llvm_unreachable("bad conversion");
4245e5dd7070Spatrick
4246e5dd7070Spatrick case ImplicitConversionSequence::BadConversion:
4247ec727ea7Spatrick Sema::AssignConvertType ConvTy =
4248ec727ea7Spatrick CheckAssignmentConstraints(From->getExprLoc(), ToType, From->getType());
4249ec727ea7Spatrick bool Diagnosed = DiagnoseAssignmentResult(
4250ec727ea7Spatrick ConvTy == Compatible ? Incompatible : ConvTy, From->getExprLoc(),
4251ec727ea7Spatrick ToType, From->getType(), From, Action);
4252e5dd7070Spatrick assert(Diagnosed && "failed to diagnose bad conversion"); (void)Diagnosed;
4253e5dd7070Spatrick return ExprError();
4254e5dd7070Spatrick }
4255e5dd7070Spatrick
4256e5dd7070Spatrick // Everything went well.
4257e5dd7070Spatrick return From;
4258e5dd7070Spatrick }
4259e5dd7070Spatrick
4260e5dd7070Spatrick /// PerformImplicitConversion - Perform an implicit conversion of the
4261e5dd7070Spatrick /// expression From to the type ToType by following the standard
4262e5dd7070Spatrick /// conversion sequence SCS. Returns the converted
4263e5dd7070Spatrick /// expression. Flavor is the context in which we're performing this
4264e5dd7070Spatrick /// conversion, for use in error messages.
4265e5dd7070Spatrick ExprResult
PerformImplicitConversion(Expr * From,QualType ToType,const StandardConversionSequence & SCS,AssignmentAction Action,CheckedConversionKind CCK)4266e5dd7070Spatrick Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4267e5dd7070Spatrick const StandardConversionSequence& SCS,
4268e5dd7070Spatrick AssignmentAction Action,
4269e5dd7070Spatrick CheckedConversionKind CCK) {
4270e5dd7070Spatrick bool CStyle = (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast);
4271e5dd7070Spatrick
4272e5dd7070Spatrick // Overall FIXME: we are recomputing too many types here and doing far too
4273e5dd7070Spatrick // much extra work. What this means is that we need to keep track of more
4274e5dd7070Spatrick // information that is computed when we try the implicit conversion initially,
4275e5dd7070Spatrick // so that we don't need to recompute anything here.
4276e5dd7070Spatrick QualType FromType = From->getType();
4277e5dd7070Spatrick
4278e5dd7070Spatrick if (SCS.CopyConstructor) {
4279e5dd7070Spatrick // FIXME: When can ToType be a reference type?
4280e5dd7070Spatrick assert(!ToType->isReferenceType());
4281e5dd7070Spatrick if (SCS.Second == ICK_Derived_To_Base) {
4282e5dd7070Spatrick SmallVector<Expr*, 8> ConstructorArgs;
4283a9ac8606Spatrick if (CompleteConstructorCall(
4284a9ac8606Spatrick cast<CXXConstructorDecl>(SCS.CopyConstructor), ToType, From,
4285a9ac8606Spatrick /*FIXME:ConstructLoc*/ SourceLocation(), ConstructorArgs))
4286e5dd7070Spatrick return ExprError();
4287e5dd7070Spatrick return BuildCXXConstructExpr(
4288e5dd7070Spatrick /*FIXME:ConstructLoc*/ SourceLocation(), ToType,
4289e5dd7070Spatrick SCS.FoundCopyConstructor, SCS.CopyConstructor,
4290e5dd7070Spatrick ConstructorArgs, /*HadMultipleCandidates*/ false,
4291e5dd7070Spatrick /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
4292e5dd7070Spatrick CXXConstructExpr::CK_Complete, SourceRange());
4293e5dd7070Spatrick }
4294e5dd7070Spatrick return BuildCXXConstructExpr(
4295e5dd7070Spatrick /*FIXME:ConstructLoc*/ SourceLocation(), ToType,
4296e5dd7070Spatrick SCS.FoundCopyConstructor, SCS.CopyConstructor,
4297e5dd7070Spatrick From, /*HadMultipleCandidates*/ false,
4298e5dd7070Spatrick /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
4299e5dd7070Spatrick CXXConstructExpr::CK_Complete, SourceRange());
4300e5dd7070Spatrick }
4301e5dd7070Spatrick
4302e5dd7070Spatrick // Resolve overloaded function references.
4303e5dd7070Spatrick if (Context.hasSameType(FromType, Context.OverloadTy)) {
4304e5dd7070Spatrick DeclAccessPair Found;
4305e5dd7070Spatrick FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType,
4306e5dd7070Spatrick true, Found);
4307e5dd7070Spatrick if (!Fn)
4308e5dd7070Spatrick return ExprError();
4309e5dd7070Spatrick
4310e5dd7070Spatrick if (DiagnoseUseOfDecl(Fn, From->getBeginLoc()))
4311e5dd7070Spatrick return ExprError();
4312e5dd7070Spatrick
4313e5dd7070Spatrick From = FixOverloadedFunctionReference(From, Found, Fn);
4314*12c85518Srobert
4315*12c85518Srobert // We might get back another placeholder expression if we resolved to a
4316*12c85518Srobert // builtin.
4317*12c85518Srobert ExprResult Checked = CheckPlaceholderExpr(From);
4318*12c85518Srobert if (Checked.isInvalid())
4319*12c85518Srobert return ExprError();
4320*12c85518Srobert
4321*12c85518Srobert From = Checked.get();
4322e5dd7070Spatrick FromType = From->getType();
4323e5dd7070Spatrick }
4324e5dd7070Spatrick
4325e5dd7070Spatrick // If we're converting to an atomic type, first convert to the corresponding
4326e5dd7070Spatrick // non-atomic type.
4327e5dd7070Spatrick QualType ToAtomicType;
4328e5dd7070Spatrick if (const AtomicType *ToAtomic = ToType->getAs<AtomicType>()) {
4329e5dd7070Spatrick ToAtomicType = ToType;
4330e5dd7070Spatrick ToType = ToAtomic->getValueType();
4331e5dd7070Spatrick }
4332e5dd7070Spatrick
4333e5dd7070Spatrick QualType InitialFromType = FromType;
4334e5dd7070Spatrick // Perform the first implicit conversion.
4335e5dd7070Spatrick switch (SCS.First) {
4336e5dd7070Spatrick case ICK_Identity:
4337e5dd7070Spatrick if (const AtomicType *FromAtomic = FromType->getAs<AtomicType>()) {
4338e5dd7070Spatrick FromType = FromAtomic->getValueType().getUnqualifiedType();
4339e5dd7070Spatrick From = ImplicitCastExpr::Create(Context, FromType, CK_AtomicToNonAtomic,
4340a9ac8606Spatrick From, /*BasePath=*/nullptr, VK_PRValue,
4341a9ac8606Spatrick FPOptionsOverride());
4342e5dd7070Spatrick }
4343e5dd7070Spatrick break;
4344e5dd7070Spatrick
4345e5dd7070Spatrick case ICK_Lvalue_To_Rvalue: {
4346e5dd7070Spatrick assert(From->getObjectKind() != OK_ObjCProperty);
4347e5dd7070Spatrick ExprResult FromRes = DefaultLvalueConversion(From);
4348a9ac8606Spatrick if (FromRes.isInvalid())
4349a9ac8606Spatrick return ExprError();
4350a9ac8606Spatrick
4351e5dd7070Spatrick From = FromRes.get();
4352e5dd7070Spatrick FromType = From->getType();
4353e5dd7070Spatrick break;
4354e5dd7070Spatrick }
4355e5dd7070Spatrick
4356e5dd7070Spatrick case ICK_Array_To_Pointer:
4357e5dd7070Spatrick FromType = Context.getArrayDecayedType(FromType);
4358a9ac8606Spatrick From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay, VK_PRValue,
4359a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4360a9ac8606Spatrick .get();
4361e5dd7070Spatrick break;
4362e5dd7070Spatrick
4363e5dd7070Spatrick case ICK_Function_To_Pointer:
4364e5dd7070Spatrick FromType = Context.getPointerType(FromType);
4365e5dd7070Spatrick From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay,
4366a9ac8606Spatrick VK_PRValue, /*BasePath=*/nullptr, CCK)
4367a9ac8606Spatrick .get();
4368e5dd7070Spatrick break;
4369e5dd7070Spatrick
4370e5dd7070Spatrick default:
4371e5dd7070Spatrick llvm_unreachable("Improper first standard conversion");
4372e5dd7070Spatrick }
4373e5dd7070Spatrick
4374e5dd7070Spatrick // Perform the second implicit conversion
4375e5dd7070Spatrick switch (SCS.Second) {
4376e5dd7070Spatrick case ICK_Identity:
4377e5dd7070Spatrick // C++ [except.spec]p5:
4378e5dd7070Spatrick // [For] assignment to and initialization of pointers to functions,
4379e5dd7070Spatrick // pointers to member functions, and references to functions: the
4380e5dd7070Spatrick // target entity shall allow at least the exceptions allowed by the
4381e5dd7070Spatrick // source value in the assignment or initialization.
4382e5dd7070Spatrick switch (Action) {
4383e5dd7070Spatrick case AA_Assigning:
4384e5dd7070Spatrick case AA_Initializing:
4385e5dd7070Spatrick // Note, function argument passing and returning are initialization.
4386e5dd7070Spatrick case AA_Passing:
4387e5dd7070Spatrick case AA_Returning:
4388e5dd7070Spatrick case AA_Sending:
4389e5dd7070Spatrick case AA_Passing_CFAudited:
4390e5dd7070Spatrick if (CheckExceptionSpecCompatibility(From, ToType))
4391e5dd7070Spatrick return ExprError();
4392e5dd7070Spatrick break;
4393e5dd7070Spatrick
4394e5dd7070Spatrick case AA_Casting:
4395e5dd7070Spatrick case AA_Converting:
4396e5dd7070Spatrick // Casts and implicit conversions are not initialization, so are not
4397e5dd7070Spatrick // checked for exception specification mismatches.
4398e5dd7070Spatrick break;
4399e5dd7070Spatrick }
4400e5dd7070Spatrick // Nothing else to do.
4401e5dd7070Spatrick break;
4402e5dd7070Spatrick
4403e5dd7070Spatrick case ICK_Integral_Promotion:
4404e5dd7070Spatrick case ICK_Integral_Conversion:
4405e5dd7070Spatrick if (ToType->isBooleanType()) {
4406e5dd7070Spatrick assert(FromType->castAs<EnumType>()->getDecl()->isFixed() &&
4407e5dd7070Spatrick SCS.Second == ICK_Integral_Promotion &&
4408e5dd7070Spatrick "only enums with fixed underlying type can promote to bool");
4409a9ac8606Spatrick From = ImpCastExprToType(From, ToType, CK_IntegralToBoolean, VK_PRValue,
4410a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4411a9ac8606Spatrick .get();
4412e5dd7070Spatrick } else {
4413a9ac8606Spatrick From = ImpCastExprToType(From, ToType, CK_IntegralCast, VK_PRValue,
4414a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4415a9ac8606Spatrick .get();
4416e5dd7070Spatrick }
4417e5dd7070Spatrick break;
4418e5dd7070Spatrick
4419e5dd7070Spatrick case ICK_Floating_Promotion:
4420e5dd7070Spatrick case ICK_Floating_Conversion:
4421a9ac8606Spatrick From = ImpCastExprToType(From, ToType, CK_FloatingCast, VK_PRValue,
4422a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4423a9ac8606Spatrick .get();
4424e5dd7070Spatrick break;
4425e5dd7070Spatrick
4426e5dd7070Spatrick case ICK_Complex_Promotion:
4427e5dd7070Spatrick case ICK_Complex_Conversion: {
4428e5dd7070Spatrick QualType FromEl = From->getType()->castAs<ComplexType>()->getElementType();
4429e5dd7070Spatrick QualType ToEl = ToType->castAs<ComplexType>()->getElementType();
4430e5dd7070Spatrick CastKind CK;
4431e5dd7070Spatrick if (FromEl->isRealFloatingType()) {
4432e5dd7070Spatrick if (ToEl->isRealFloatingType())
4433e5dd7070Spatrick CK = CK_FloatingComplexCast;
4434e5dd7070Spatrick else
4435e5dd7070Spatrick CK = CK_FloatingComplexToIntegralComplex;
4436e5dd7070Spatrick } else if (ToEl->isRealFloatingType()) {
4437e5dd7070Spatrick CK = CK_IntegralComplexToFloatingComplex;
4438e5dd7070Spatrick } else {
4439e5dd7070Spatrick CK = CK_IntegralComplexCast;
4440e5dd7070Spatrick }
4441a9ac8606Spatrick From = ImpCastExprToType(From, ToType, CK, VK_PRValue, /*BasePath=*/nullptr,
4442a9ac8606Spatrick CCK)
4443a9ac8606Spatrick .get();
4444e5dd7070Spatrick break;
4445e5dd7070Spatrick }
4446e5dd7070Spatrick
4447e5dd7070Spatrick case ICK_Floating_Integral:
4448e5dd7070Spatrick if (ToType->isRealFloatingType())
4449a9ac8606Spatrick From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue,
4450a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4451a9ac8606Spatrick .get();
4452e5dd7070Spatrick else
4453a9ac8606Spatrick From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral, VK_PRValue,
4454a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4455a9ac8606Spatrick .get();
4456e5dd7070Spatrick break;
4457e5dd7070Spatrick
4458e5dd7070Spatrick case ICK_Compatible_Conversion:
4459ec727ea7Spatrick From = ImpCastExprToType(From, ToType, CK_NoOp, From->getValueKind(),
4460ec727ea7Spatrick /*BasePath=*/nullptr, CCK).get();
4461e5dd7070Spatrick break;
4462e5dd7070Spatrick
4463e5dd7070Spatrick case ICK_Writeback_Conversion:
4464e5dd7070Spatrick case ICK_Pointer_Conversion: {
4465e5dd7070Spatrick if (SCS.IncompatibleObjC && Action != AA_Casting) {
4466e5dd7070Spatrick // Diagnose incompatible Objective-C conversions
4467e5dd7070Spatrick if (Action == AA_Initializing || Action == AA_Assigning)
4468e5dd7070Spatrick Diag(From->getBeginLoc(),
4469e5dd7070Spatrick diag::ext_typecheck_convert_incompatible_pointer)
4470e5dd7070Spatrick << ToType << From->getType() << Action << From->getSourceRange()
4471e5dd7070Spatrick << 0;
4472e5dd7070Spatrick else
4473e5dd7070Spatrick Diag(From->getBeginLoc(),
4474e5dd7070Spatrick diag::ext_typecheck_convert_incompatible_pointer)
4475e5dd7070Spatrick << From->getType() << ToType << Action << From->getSourceRange()
4476e5dd7070Spatrick << 0;
4477e5dd7070Spatrick
4478e5dd7070Spatrick if (From->getType()->isObjCObjectPointerType() &&
4479e5dd7070Spatrick ToType->isObjCObjectPointerType())
4480e5dd7070Spatrick EmitRelatedResultTypeNote(From);
4481e5dd7070Spatrick } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
4482e5dd7070Spatrick !CheckObjCARCUnavailableWeakConversion(ToType,
4483e5dd7070Spatrick From->getType())) {
4484e5dd7070Spatrick if (Action == AA_Initializing)
4485e5dd7070Spatrick Diag(From->getBeginLoc(), diag::err_arc_weak_unavailable_assign);
4486e5dd7070Spatrick else
4487e5dd7070Spatrick Diag(From->getBeginLoc(), diag::err_arc_convesion_of_weak_unavailable)
4488e5dd7070Spatrick << (Action == AA_Casting) << From->getType() << ToType
4489e5dd7070Spatrick << From->getSourceRange();
4490e5dd7070Spatrick }
4491e5dd7070Spatrick
4492e5dd7070Spatrick // Defer address space conversion to the third conversion.
4493e5dd7070Spatrick QualType FromPteeType = From->getType()->getPointeeType();
4494e5dd7070Spatrick QualType ToPteeType = ToType->getPointeeType();
4495e5dd7070Spatrick QualType NewToType = ToType;
4496e5dd7070Spatrick if (!FromPteeType.isNull() && !ToPteeType.isNull() &&
4497e5dd7070Spatrick FromPteeType.getAddressSpace() != ToPteeType.getAddressSpace()) {
4498e5dd7070Spatrick NewToType = Context.removeAddrSpaceQualType(ToPteeType);
4499e5dd7070Spatrick NewToType = Context.getAddrSpaceQualType(NewToType,
4500e5dd7070Spatrick FromPteeType.getAddressSpace());
4501e5dd7070Spatrick if (ToType->isObjCObjectPointerType())
4502e5dd7070Spatrick NewToType = Context.getObjCObjectPointerType(NewToType);
4503e5dd7070Spatrick else if (ToType->isBlockPointerType())
4504e5dd7070Spatrick NewToType = Context.getBlockPointerType(NewToType);
4505e5dd7070Spatrick else
4506e5dd7070Spatrick NewToType = Context.getPointerType(NewToType);
4507e5dd7070Spatrick }
4508e5dd7070Spatrick
4509e5dd7070Spatrick CastKind Kind;
4510e5dd7070Spatrick CXXCastPath BasePath;
4511e5dd7070Spatrick if (CheckPointerConversion(From, NewToType, Kind, BasePath, CStyle))
4512e5dd7070Spatrick return ExprError();
4513e5dd7070Spatrick
4514e5dd7070Spatrick // Make sure we extend blocks if necessary.
4515e5dd7070Spatrick // FIXME: doing this here is really ugly.
4516e5dd7070Spatrick if (Kind == CK_BlockPointerToObjCPointerCast) {
4517e5dd7070Spatrick ExprResult E = From;
4518e5dd7070Spatrick (void) PrepareCastToObjCObjectPointer(E);
4519e5dd7070Spatrick From = E.get();
4520e5dd7070Spatrick }
4521e5dd7070Spatrick if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
4522e5dd7070Spatrick CheckObjCConversion(SourceRange(), NewToType, From, CCK);
4523a9ac8606Spatrick From = ImpCastExprToType(From, NewToType, Kind, VK_PRValue, &BasePath, CCK)
4524e5dd7070Spatrick .get();
4525e5dd7070Spatrick break;
4526e5dd7070Spatrick }
4527e5dd7070Spatrick
4528e5dd7070Spatrick case ICK_Pointer_Member: {
4529e5dd7070Spatrick CastKind Kind;
4530e5dd7070Spatrick CXXCastPath BasePath;
4531e5dd7070Spatrick if (CheckMemberPointerConversion(From, ToType, Kind, BasePath, CStyle))
4532e5dd7070Spatrick return ExprError();
4533e5dd7070Spatrick if (CheckExceptionSpecCompatibility(From, ToType))
4534e5dd7070Spatrick return ExprError();
4535e5dd7070Spatrick
4536e5dd7070Spatrick // We may not have been able to figure out what this member pointer resolved
4537e5dd7070Spatrick // to up until this exact point. Attempt to lock-in it's inheritance model.
4538e5dd7070Spatrick if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
4539e5dd7070Spatrick (void)isCompleteType(From->getExprLoc(), From->getType());
4540e5dd7070Spatrick (void)isCompleteType(From->getExprLoc(), ToType);
4541e5dd7070Spatrick }
4542e5dd7070Spatrick
4543a9ac8606Spatrick From =
4544a9ac8606Spatrick ImpCastExprToType(From, ToType, Kind, VK_PRValue, &BasePath, CCK).get();
4545e5dd7070Spatrick break;
4546e5dd7070Spatrick }
4547e5dd7070Spatrick
4548e5dd7070Spatrick case ICK_Boolean_Conversion:
4549e5dd7070Spatrick // Perform half-to-boolean conversion via float.
4550e5dd7070Spatrick if (From->getType()->isHalfType()) {
4551e5dd7070Spatrick From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).get();
4552e5dd7070Spatrick FromType = Context.FloatTy;
4553e5dd7070Spatrick }
4554e5dd7070Spatrick
4555e5dd7070Spatrick From = ImpCastExprToType(From, Context.BoolTy,
4556a9ac8606Spatrick ScalarTypeToBooleanCastKind(FromType), VK_PRValue,
4557a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4558a9ac8606Spatrick .get();
4559e5dd7070Spatrick break;
4560e5dd7070Spatrick
4561e5dd7070Spatrick case ICK_Derived_To_Base: {
4562e5dd7070Spatrick CXXCastPath BasePath;
4563e5dd7070Spatrick if (CheckDerivedToBaseConversion(
4564e5dd7070Spatrick From->getType(), ToType.getNonReferenceType(), From->getBeginLoc(),
4565e5dd7070Spatrick From->getSourceRange(), &BasePath, CStyle))
4566e5dd7070Spatrick return ExprError();
4567e5dd7070Spatrick
4568e5dd7070Spatrick From = ImpCastExprToType(From, ToType.getNonReferenceType(),
4569e5dd7070Spatrick CK_DerivedToBase, From->getValueKind(),
4570e5dd7070Spatrick &BasePath, CCK).get();
4571e5dd7070Spatrick break;
4572e5dd7070Spatrick }
4573e5dd7070Spatrick
4574e5dd7070Spatrick case ICK_Vector_Conversion:
4575a9ac8606Spatrick From = ImpCastExprToType(From, ToType, CK_BitCast, VK_PRValue,
4576a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4577a9ac8606Spatrick .get();
4578a9ac8606Spatrick break;
4579a9ac8606Spatrick
4580a9ac8606Spatrick case ICK_SVE_Vector_Conversion:
4581a9ac8606Spatrick From = ImpCastExprToType(From, ToType, CK_BitCast, VK_PRValue,
4582a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4583a9ac8606Spatrick .get();
4584e5dd7070Spatrick break;
4585e5dd7070Spatrick
4586e5dd7070Spatrick case ICK_Vector_Splat: {
4587e5dd7070Spatrick // Vector splat from any arithmetic type to a vector.
4588e5dd7070Spatrick Expr *Elem = prepareVectorSplat(ToType, From).get();
4589a9ac8606Spatrick From = ImpCastExprToType(Elem, ToType, CK_VectorSplat, VK_PRValue,
4590a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4591a9ac8606Spatrick .get();
4592e5dd7070Spatrick break;
4593e5dd7070Spatrick }
4594e5dd7070Spatrick
4595e5dd7070Spatrick case ICK_Complex_Real:
4596e5dd7070Spatrick // Case 1. x -> _Complex y
4597e5dd7070Spatrick if (const ComplexType *ToComplex = ToType->getAs<ComplexType>()) {
4598e5dd7070Spatrick QualType ElType = ToComplex->getElementType();
4599e5dd7070Spatrick bool isFloatingComplex = ElType->isRealFloatingType();
4600e5dd7070Spatrick
4601e5dd7070Spatrick // x -> y
4602e5dd7070Spatrick if (Context.hasSameUnqualifiedType(ElType, From->getType())) {
4603e5dd7070Spatrick // do nothing
4604e5dd7070Spatrick } else if (From->getType()->isRealFloatingType()) {
4605e5dd7070Spatrick From = ImpCastExprToType(From, ElType,
4606e5dd7070Spatrick isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).get();
4607e5dd7070Spatrick } else {
4608e5dd7070Spatrick assert(From->getType()->isIntegerType());
4609e5dd7070Spatrick From = ImpCastExprToType(From, ElType,
4610e5dd7070Spatrick isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).get();
4611e5dd7070Spatrick }
4612e5dd7070Spatrick // y -> _Complex y
4613e5dd7070Spatrick From = ImpCastExprToType(From, ToType,
4614e5dd7070Spatrick isFloatingComplex ? CK_FloatingRealToComplex
4615e5dd7070Spatrick : CK_IntegralRealToComplex).get();
4616e5dd7070Spatrick
4617e5dd7070Spatrick // Case 2. _Complex x -> y
4618e5dd7070Spatrick } else {
4619ec727ea7Spatrick auto *FromComplex = From->getType()->castAs<ComplexType>();
4620e5dd7070Spatrick QualType ElType = FromComplex->getElementType();
4621e5dd7070Spatrick bool isFloatingComplex = ElType->isRealFloatingType();
4622e5dd7070Spatrick
4623e5dd7070Spatrick // _Complex x -> x
4624e5dd7070Spatrick From = ImpCastExprToType(From, ElType,
4625e5dd7070Spatrick isFloatingComplex ? CK_FloatingComplexToReal
4626e5dd7070Spatrick : CK_IntegralComplexToReal,
4627a9ac8606Spatrick VK_PRValue, /*BasePath=*/nullptr, CCK)
4628a9ac8606Spatrick .get();
4629e5dd7070Spatrick
4630e5dd7070Spatrick // x -> y
4631e5dd7070Spatrick if (Context.hasSameUnqualifiedType(ElType, ToType)) {
4632e5dd7070Spatrick // do nothing
4633e5dd7070Spatrick } else if (ToType->isRealFloatingType()) {
4634e5dd7070Spatrick From = ImpCastExprToType(From, ToType,
4635a9ac8606Spatrick isFloatingComplex ? CK_FloatingCast
4636a9ac8606Spatrick : CK_IntegralToFloating,
4637a9ac8606Spatrick VK_PRValue, /*BasePath=*/nullptr, CCK)
4638a9ac8606Spatrick .get();
4639e5dd7070Spatrick } else {
4640e5dd7070Spatrick assert(ToType->isIntegerType());
4641e5dd7070Spatrick From = ImpCastExprToType(From, ToType,
4642a9ac8606Spatrick isFloatingComplex ? CK_FloatingToIntegral
4643a9ac8606Spatrick : CK_IntegralCast,
4644a9ac8606Spatrick VK_PRValue, /*BasePath=*/nullptr, CCK)
4645a9ac8606Spatrick .get();
4646e5dd7070Spatrick }
4647e5dd7070Spatrick }
4648e5dd7070Spatrick break;
4649e5dd7070Spatrick
4650e5dd7070Spatrick case ICK_Block_Pointer_Conversion: {
4651e5dd7070Spatrick LangAS AddrSpaceL =
4652e5dd7070Spatrick ToType->castAs<BlockPointerType>()->getPointeeType().getAddressSpace();
4653e5dd7070Spatrick LangAS AddrSpaceR =
4654e5dd7070Spatrick FromType->castAs<BlockPointerType>()->getPointeeType().getAddressSpace();
4655e5dd7070Spatrick assert(Qualifiers::isAddressSpaceSupersetOf(AddrSpaceL, AddrSpaceR) &&
4656e5dd7070Spatrick "Invalid cast");
4657e5dd7070Spatrick CastKind Kind =
4658e5dd7070Spatrick AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast;
4659e5dd7070Spatrick From = ImpCastExprToType(From, ToType.getUnqualifiedType(), Kind,
4660a9ac8606Spatrick VK_PRValue, /*BasePath=*/nullptr, CCK)
4661a9ac8606Spatrick .get();
4662e5dd7070Spatrick break;
4663e5dd7070Spatrick }
4664e5dd7070Spatrick
4665e5dd7070Spatrick case ICK_TransparentUnionConversion: {
4666e5dd7070Spatrick ExprResult FromRes = From;
4667e5dd7070Spatrick Sema::AssignConvertType ConvTy =
4668e5dd7070Spatrick CheckTransparentUnionArgumentConstraints(ToType, FromRes);
4669e5dd7070Spatrick if (FromRes.isInvalid())
4670e5dd7070Spatrick return ExprError();
4671e5dd7070Spatrick From = FromRes.get();
4672e5dd7070Spatrick assert ((ConvTy == Sema::Compatible) &&
4673e5dd7070Spatrick "Improper transparent union conversion");
4674e5dd7070Spatrick (void)ConvTy;
4675e5dd7070Spatrick break;
4676e5dd7070Spatrick }
4677e5dd7070Spatrick
4678e5dd7070Spatrick case ICK_Zero_Event_Conversion:
4679e5dd7070Spatrick case ICK_Zero_Queue_Conversion:
4680e5dd7070Spatrick From = ImpCastExprToType(From, ToType,
4681e5dd7070Spatrick CK_ZeroToOCLOpaqueType,
4682e5dd7070Spatrick From->getValueKind()).get();
4683e5dd7070Spatrick break;
4684e5dd7070Spatrick
4685e5dd7070Spatrick case ICK_Lvalue_To_Rvalue:
4686e5dd7070Spatrick case ICK_Array_To_Pointer:
4687e5dd7070Spatrick case ICK_Function_To_Pointer:
4688e5dd7070Spatrick case ICK_Function_Conversion:
4689e5dd7070Spatrick case ICK_Qualification:
4690e5dd7070Spatrick case ICK_Num_Conversion_Kinds:
4691e5dd7070Spatrick case ICK_C_Only_Conversion:
4692e5dd7070Spatrick case ICK_Incompatible_Pointer_Conversion:
4693e5dd7070Spatrick llvm_unreachable("Improper second standard conversion");
4694e5dd7070Spatrick }
4695e5dd7070Spatrick
4696e5dd7070Spatrick switch (SCS.Third) {
4697e5dd7070Spatrick case ICK_Identity:
4698e5dd7070Spatrick // Nothing to do.
4699e5dd7070Spatrick break;
4700e5dd7070Spatrick
4701e5dd7070Spatrick case ICK_Function_Conversion:
4702e5dd7070Spatrick // If both sides are functions (or pointers/references to them), there could
4703e5dd7070Spatrick // be incompatible exception declarations.
4704e5dd7070Spatrick if (CheckExceptionSpecCompatibility(From, ToType))
4705e5dd7070Spatrick return ExprError();
4706e5dd7070Spatrick
4707a9ac8606Spatrick From = ImpCastExprToType(From, ToType, CK_NoOp, VK_PRValue,
4708a9ac8606Spatrick /*BasePath=*/nullptr, CCK)
4709a9ac8606Spatrick .get();
4710e5dd7070Spatrick break;
4711e5dd7070Spatrick
4712e5dd7070Spatrick case ICK_Qualification: {
4713ec727ea7Spatrick ExprValueKind VK = From->getValueKind();
4714e5dd7070Spatrick CastKind CK = CK_NoOp;
4715e5dd7070Spatrick
4716e5dd7070Spatrick if (ToType->isReferenceType() &&
4717e5dd7070Spatrick ToType->getPointeeType().getAddressSpace() !=
4718e5dd7070Spatrick From->getType().getAddressSpace())
4719e5dd7070Spatrick CK = CK_AddressSpaceConversion;
4720e5dd7070Spatrick
4721e5dd7070Spatrick if (ToType->isPointerType() &&
4722e5dd7070Spatrick ToType->getPointeeType().getAddressSpace() !=
4723e5dd7070Spatrick From->getType()->getPointeeType().getAddressSpace())
4724e5dd7070Spatrick CK = CK_AddressSpaceConversion;
4725e5dd7070Spatrick
4726*12c85518Srobert if (!isCast(CCK) &&
4727*12c85518Srobert !ToType->getPointeeType().getQualifiers().hasUnaligned() &&
4728*12c85518Srobert From->getType()->getPointeeType().getQualifiers().hasUnaligned()) {
4729*12c85518Srobert Diag(From->getBeginLoc(), diag::warn_imp_cast_drops_unaligned)
4730*12c85518Srobert << InitialFromType << ToType;
4731*12c85518Srobert }
4732*12c85518Srobert
4733e5dd7070Spatrick From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context), CK, VK,
4734e5dd7070Spatrick /*BasePath=*/nullptr, CCK)
4735e5dd7070Spatrick .get();
4736e5dd7070Spatrick
4737e5dd7070Spatrick if (SCS.DeprecatedStringLiteralToCharPtr &&
4738e5dd7070Spatrick !getLangOpts().WritableStrings) {
4739e5dd7070Spatrick Diag(From->getBeginLoc(),
4740e5dd7070Spatrick getLangOpts().CPlusPlus11
4741e5dd7070Spatrick ? diag::ext_deprecated_string_literal_conversion
4742e5dd7070Spatrick : diag::warn_deprecated_string_literal_conversion)
4743e5dd7070Spatrick << ToType.getNonReferenceType();
4744e5dd7070Spatrick }
4745e5dd7070Spatrick
4746e5dd7070Spatrick break;
4747e5dd7070Spatrick }
4748e5dd7070Spatrick
4749e5dd7070Spatrick default:
4750e5dd7070Spatrick llvm_unreachable("Improper third standard conversion");
4751e5dd7070Spatrick }
4752e5dd7070Spatrick
4753e5dd7070Spatrick // If this conversion sequence involved a scalar -> atomic conversion, perform
4754e5dd7070Spatrick // that conversion now.
4755e5dd7070Spatrick if (!ToAtomicType.isNull()) {
4756e5dd7070Spatrick assert(Context.hasSameType(
4757e5dd7070Spatrick ToAtomicType->castAs<AtomicType>()->getValueType(), From->getType()));
4758e5dd7070Spatrick From = ImpCastExprToType(From, ToAtomicType, CK_NonAtomicToAtomic,
4759a9ac8606Spatrick VK_PRValue, nullptr, CCK)
4760a9ac8606Spatrick .get();
4761e5dd7070Spatrick }
4762e5dd7070Spatrick
4763ec727ea7Spatrick // Materialize a temporary if we're implicitly converting to a reference
4764ec727ea7Spatrick // type. This is not required by the C++ rules but is necessary to maintain
4765ec727ea7Spatrick // AST invariants.
4766a9ac8606Spatrick if (ToType->isReferenceType() && From->isPRValue()) {
4767ec727ea7Spatrick ExprResult Res = TemporaryMaterializationConversion(From);
4768ec727ea7Spatrick if (Res.isInvalid())
4769ec727ea7Spatrick return ExprError();
4770ec727ea7Spatrick From = Res.get();
4771ec727ea7Spatrick }
4772ec727ea7Spatrick
4773e5dd7070Spatrick // If this conversion sequence succeeded and involved implicitly converting a
4774e5dd7070Spatrick // _Nullable type to a _Nonnull one, complain.
4775e5dd7070Spatrick if (!isCast(CCK))
4776e5dd7070Spatrick diagnoseNullableToNonnullConversion(ToType, InitialFromType,
4777e5dd7070Spatrick From->getBeginLoc());
4778e5dd7070Spatrick
4779e5dd7070Spatrick return From;
4780e5dd7070Spatrick }
4781e5dd7070Spatrick
4782e5dd7070Spatrick /// Check the completeness of a type in a unary type trait.
4783e5dd7070Spatrick ///
4784e5dd7070Spatrick /// If the particular type trait requires a complete type, tries to complete
4785e5dd7070Spatrick /// it. If completing the type fails, a diagnostic is emitted and false
4786e5dd7070Spatrick /// returned. If completing the type succeeds or no completion was required,
4787e5dd7070Spatrick /// returns true.
CheckUnaryTypeTraitTypeCompleteness(Sema & S,TypeTrait UTT,SourceLocation Loc,QualType ArgTy)4788e5dd7070Spatrick static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
4789e5dd7070Spatrick SourceLocation Loc,
4790e5dd7070Spatrick QualType ArgTy) {
4791e5dd7070Spatrick // C++0x [meta.unary.prop]p3:
4792e5dd7070Spatrick // For all of the class templates X declared in this Clause, instantiating
4793e5dd7070Spatrick // that template with a template argument that is a class template
4794e5dd7070Spatrick // specialization may result in the implicit instantiation of the template
4795e5dd7070Spatrick // argument if and only if the semantics of X require that the argument
4796e5dd7070Spatrick // must be a complete type.
4797e5dd7070Spatrick // We apply this rule to all the type trait expressions used to implement
4798e5dd7070Spatrick // these class templates. We also try to follow any GCC documented behavior
4799e5dd7070Spatrick // in these expressions to ensure portability of standard libraries.
4800e5dd7070Spatrick switch (UTT) {
4801e5dd7070Spatrick default: llvm_unreachable("not a UTT");
4802e5dd7070Spatrick // is_complete_type somewhat obviously cannot require a complete type.
4803e5dd7070Spatrick case UTT_IsCompleteType:
4804e5dd7070Spatrick // Fall-through
4805e5dd7070Spatrick
4806e5dd7070Spatrick // These traits are modeled on the type predicates in C++0x
4807e5dd7070Spatrick // [meta.unary.cat] and [meta.unary.comp]. They are not specified as
4808e5dd7070Spatrick // requiring a complete type, as whether or not they return true cannot be
4809e5dd7070Spatrick // impacted by the completeness of the type.
4810e5dd7070Spatrick case UTT_IsVoid:
4811e5dd7070Spatrick case UTT_IsIntegral:
4812e5dd7070Spatrick case UTT_IsFloatingPoint:
4813e5dd7070Spatrick case UTT_IsArray:
4814*12c85518Srobert case UTT_IsBoundedArray:
4815e5dd7070Spatrick case UTT_IsPointer:
4816*12c85518Srobert case UTT_IsNullPointer:
4817*12c85518Srobert case UTT_IsReferenceable:
4818e5dd7070Spatrick case UTT_IsLvalueReference:
4819e5dd7070Spatrick case UTT_IsRvalueReference:
4820e5dd7070Spatrick case UTT_IsMemberFunctionPointer:
4821e5dd7070Spatrick case UTT_IsMemberObjectPointer:
4822e5dd7070Spatrick case UTT_IsEnum:
4823*12c85518Srobert case UTT_IsScopedEnum:
4824e5dd7070Spatrick case UTT_IsUnion:
4825e5dd7070Spatrick case UTT_IsClass:
4826e5dd7070Spatrick case UTT_IsFunction:
4827e5dd7070Spatrick case UTT_IsReference:
4828e5dd7070Spatrick case UTT_IsArithmetic:
4829e5dd7070Spatrick case UTT_IsFundamental:
4830e5dd7070Spatrick case UTT_IsObject:
4831e5dd7070Spatrick case UTT_IsScalar:
4832e5dd7070Spatrick case UTT_IsCompound:
4833e5dd7070Spatrick case UTT_IsMemberPointer:
4834e5dd7070Spatrick // Fall-through
4835e5dd7070Spatrick
4836e5dd7070Spatrick // These traits are modeled on type predicates in C++0x [meta.unary.prop]
4837e5dd7070Spatrick // which requires some of its traits to have the complete type. However,
4838e5dd7070Spatrick // the completeness of the type cannot impact these traits' semantics, and
4839e5dd7070Spatrick // so they don't require it. This matches the comments on these traits in
4840e5dd7070Spatrick // Table 49.
4841e5dd7070Spatrick case UTT_IsConst:
4842e5dd7070Spatrick case UTT_IsVolatile:
4843e5dd7070Spatrick case UTT_IsSigned:
4844*12c85518Srobert case UTT_IsUnboundedArray:
4845e5dd7070Spatrick case UTT_IsUnsigned:
4846e5dd7070Spatrick
4847e5dd7070Spatrick // This type trait always returns false, checking the type is moot.
4848e5dd7070Spatrick case UTT_IsInterfaceClass:
4849e5dd7070Spatrick return true;
4850e5dd7070Spatrick
4851e5dd7070Spatrick // C++14 [meta.unary.prop]:
4852e5dd7070Spatrick // If T is a non-union class type, T shall be a complete type.
4853e5dd7070Spatrick case UTT_IsEmpty:
4854e5dd7070Spatrick case UTT_IsPolymorphic:
4855e5dd7070Spatrick case UTT_IsAbstract:
4856e5dd7070Spatrick if (const auto *RD = ArgTy->getAsCXXRecordDecl())
4857e5dd7070Spatrick if (!RD->isUnion())
4858e5dd7070Spatrick return !S.RequireCompleteType(
4859e5dd7070Spatrick Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
4860e5dd7070Spatrick return true;
4861e5dd7070Spatrick
4862e5dd7070Spatrick // C++14 [meta.unary.prop]:
4863e5dd7070Spatrick // If T is a class type, T shall be a complete type.
4864e5dd7070Spatrick case UTT_IsFinal:
4865e5dd7070Spatrick case UTT_IsSealed:
4866e5dd7070Spatrick if (ArgTy->getAsCXXRecordDecl())
4867e5dd7070Spatrick return !S.RequireCompleteType(
4868e5dd7070Spatrick Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
4869e5dd7070Spatrick return true;
4870e5dd7070Spatrick
4871*12c85518Srobert // LWG3823: T shall be an array type, a complete type, or cv void.
4872*12c85518Srobert case UTT_IsAggregate:
4873*12c85518Srobert if (ArgTy->isArrayType() || ArgTy->isVoidType())
4874*12c85518Srobert return true;
4875*12c85518Srobert
4876*12c85518Srobert return !S.RequireCompleteType(
4877*12c85518Srobert Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
4878*12c85518Srobert
4879e5dd7070Spatrick // C++1z [meta.unary.prop]:
4880e5dd7070Spatrick // remove_all_extents_t<T> shall be a complete type or cv void.
4881e5dd7070Spatrick case UTT_IsTrivial:
4882e5dd7070Spatrick case UTT_IsTriviallyCopyable:
4883e5dd7070Spatrick case UTT_IsStandardLayout:
4884e5dd7070Spatrick case UTT_IsPOD:
4885e5dd7070Spatrick case UTT_IsLiteral:
4886*12c85518Srobert // By analogy, is_trivially_relocatable imposes the same constraints.
4887*12c85518Srobert case UTT_IsTriviallyRelocatable:
4888e5dd7070Spatrick // Per the GCC type traits documentation, T shall be a complete type, cv void,
4889e5dd7070Spatrick // or an array of unknown bound. But GCC actually imposes the same constraints
4890e5dd7070Spatrick // as above.
4891e5dd7070Spatrick case UTT_HasNothrowAssign:
4892e5dd7070Spatrick case UTT_HasNothrowMoveAssign:
4893e5dd7070Spatrick case UTT_HasNothrowConstructor:
4894e5dd7070Spatrick case UTT_HasNothrowCopy:
4895e5dd7070Spatrick case UTT_HasTrivialAssign:
4896e5dd7070Spatrick case UTT_HasTrivialMoveAssign:
4897e5dd7070Spatrick case UTT_HasTrivialDefaultConstructor:
4898e5dd7070Spatrick case UTT_HasTrivialMoveConstructor:
4899e5dd7070Spatrick case UTT_HasTrivialCopy:
4900e5dd7070Spatrick case UTT_HasTrivialDestructor:
4901e5dd7070Spatrick case UTT_HasVirtualDestructor:
4902e5dd7070Spatrick ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);
4903*12c85518Srobert [[fallthrough]];
4904e5dd7070Spatrick
4905e5dd7070Spatrick // C++1z [meta.unary.prop]:
4906e5dd7070Spatrick // T shall be a complete type, cv void, or an array of unknown bound.
4907e5dd7070Spatrick case UTT_IsDestructible:
4908e5dd7070Spatrick case UTT_IsNothrowDestructible:
4909e5dd7070Spatrick case UTT_IsTriviallyDestructible:
4910e5dd7070Spatrick case UTT_HasUniqueObjectRepresentations:
4911e5dd7070Spatrick if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
4912e5dd7070Spatrick return true;
4913e5dd7070Spatrick
4914e5dd7070Spatrick return !S.RequireCompleteType(
4915e5dd7070Spatrick Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
4916e5dd7070Spatrick }
4917e5dd7070Spatrick }
4918e5dd7070Spatrick
HasNoThrowOperator(const RecordType * RT,OverloadedOperatorKind Op,Sema & Self,SourceLocation KeyLoc,ASTContext & C,bool (CXXRecordDecl::* HasTrivial)()const,bool (CXXRecordDecl::* HasNonTrivial)()const,bool (CXXMethodDecl::* IsDesiredOp)()const)4919e5dd7070Spatrick static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op,
4920e5dd7070Spatrick Sema &Self, SourceLocation KeyLoc, ASTContext &C,
4921e5dd7070Spatrick bool (CXXRecordDecl::*HasTrivial)() const,
4922e5dd7070Spatrick bool (CXXRecordDecl::*HasNonTrivial)() const,
4923e5dd7070Spatrick bool (CXXMethodDecl::*IsDesiredOp)() const)
4924e5dd7070Spatrick {
4925e5dd7070Spatrick CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
4926e5dd7070Spatrick if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())
4927e5dd7070Spatrick return true;
4928e5dd7070Spatrick
4929e5dd7070Spatrick DeclarationName Name = C.DeclarationNames.getCXXOperatorName(Op);
4930e5dd7070Spatrick DeclarationNameInfo NameInfo(Name, KeyLoc);
4931e5dd7070Spatrick LookupResult Res(Self, NameInfo, Sema::LookupOrdinaryName);
4932e5dd7070Spatrick if (Self.LookupQualifiedName(Res, RD)) {
4933e5dd7070Spatrick bool FoundOperator = false;
4934e5dd7070Spatrick Res.suppressDiagnostics();
4935e5dd7070Spatrick for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end();
4936e5dd7070Spatrick Op != OpEnd; ++Op) {
4937e5dd7070Spatrick if (isa<FunctionTemplateDecl>(*Op))
4938e5dd7070Spatrick continue;
4939e5dd7070Spatrick
4940e5dd7070Spatrick CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);
4941e5dd7070Spatrick if((Operator->*IsDesiredOp)()) {
4942e5dd7070Spatrick FoundOperator = true;
4943ec727ea7Spatrick auto *CPT = Operator->getType()->castAs<FunctionProtoType>();
4944e5dd7070Spatrick CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
4945e5dd7070Spatrick if (!CPT || !CPT->isNothrow())
4946e5dd7070Spatrick return false;
4947e5dd7070Spatrick }
4948e5dd7070Spatrick }
4949e5dd7070Spatrick return FoundOperator;
4950e5dd7070Spatrick }
4951e5dd7070Spatrick return false;
4952e5dd7070Spatrick }
4953e5dd7070Spatrick
EvaluateUnaryTypeTrait(Sema & Self,TypeTrait UTT,SourceLocation KeyLoc,QualType T)4954e5dd7070Spatrick static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
4955e5dd7070Spatrick SourceLocation KeyLoc, QualType T) {
4956e5dd7070Spatrick assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
4957e5dd7070Spatrick
4958e5dd7070Spatrick ASTContext &C = Self.Context;
4959e5dd7070Spatrick switch(UTT) {
4960e5dd7070Spatrick default: llvm_unreachable("not a UTT");
4961e5dd7070Spatrick // Type trait expressions corresponding to the primary type category
4962e5dd7070Spatrick // predicates in C++0x [meta.unary.cat].
4963e5dd7070Spatrick case UTT_IsVoid:
4964e5dd7070Spatrick return T->isVoidType();
4965e5dd7070Spatrick case UTT_IsIntegral:
4966e5dd7070Spatrick return T->isIntegralType(C);
4967e5dd7070Spatrick case UTT_IsFloatingPoint:
4968e5dd7070Spatrick return T->isFloatingType();
4969e5dd7070Spatrick case UTT_IsArray:
4970e5dd7070Spatrick return T->isArrayType();
4971*12c85518Srobert case UTT_IsBoundedArray:
4972*12c85518Srobert if (!T->isVariableArrayType()) {
4973*12c85518Srobert return T->isArrayType() && !T->isIncompleteArrayType();
4974*12c85518Srobert }
4975*12c85518Srobert
4976*12c85518Srobert Self.Diag(KeyLoc, diag::err_vla_unsupported)
4977*12c85518Srobert << 1 << tok::kw___is_bounded_array;
4978*12c85518Srobert return false;
4979*12c85518Srobert case UTT_IsUnboundedArray:
4980*12c85518Srobert if (!T->isVariableArrayType()) {
4981*12c85518Srobert return T->isIncompleteArrayType();
4982*12c85518Srobert }
4983*12c85518Srobert
4984*12c85518Srobert Self.Diag(KeyLoc, diag::err_vla_unsupported)
4985*12c85518Srobert << 1 << tok::kw___is_unbounded_array;
4986*12c85518Srobert return false;
4987e5dd7070Spatrick case UTT_IsPointer:
4988ec727ea7Spatrick return T->isAnyPointerType();
4989*12c85518Srobert case UTT_IsNullPointer:
4990*12c85518Srobert return T->isNullPtrType();
4991e5dd7070Spatrick case UTT_IsLvalueReference:
4992e5dd7070Spatrick return T->isLValueReferenceType();
4993e5dd7070Spatrick case UTT_IsRvalueReference:
4994e5dd7070Spatrick return T->isRValueReferenceType();
4995e5dd7070Spatrick case UTT_IsMemberFunctionPointer:
4996e5dd7070Spatrick return T->isMemberFunctionPointerType();
4997e5dd7070Spatrick case UTT_IsMemberObjectPointer:
4998e5dd7070Spatrick return T->isMemberDataPointerType();
4999e5dd7070Spatrick case UTT_IsEnum:
5000e5dd7070Spatrick return T->isEnumeralType();
5001*12c85518Srobert case UTT_IsScopedEnum:
5002*12c85518Srobert return T->isScopedEnumeralType();
5003e5dd7070Spatrick case UTT_IsUnion:
5004e5dd7070Spatrick return T->isUnionType();
5005e5dd7070Spatrick case UTT_IsClass:
5006e5dd7070Spatrick return T->isClassType() || T->isStructureType() || T->isInterfaceType();
5007e5dd7070Spatrick case UTT_IsFunction:
5008e5dd7070Spatrick return T->isFunctionType();
5009e5dd7070Spatrick
5010e5dd7070Spatrick // Type trait expressions which correspond to the convenient composition
5011e5dd7070Spatrick // predicates in C++0x [meta.unary.comp].
5012e5dd7070Spatrick case UTT_IsReference:
5013e5dd7070Spatrick return T->isReferenceType();
5014e5dd7070Spatrick case UTT_IsArithmetic:
5015e5dd7070Spatrick return T->isArithmeticType() && !T->isEnumeralType();
5016e5dd7070Spatrick case UTT_IsFundamental:
5017e5dd7070Spatrick return T->isFundamentalType();
5018e5dd7070Spatrick case UTT_IsObject:
5019e5dd7070Spatrick return T->isObjectType();
5020e5dd7070Spatrick case UTT_IsScalar:
5021e5dd7070Spatrick // Note: semantic analysis depends on Objective-C lifetime types to be
5022e5dd7070Spatrick // considered scalar types. However, such types do not actually behave
5023e5dd7070Spatrick // like scalar types at run time (since they may require retain/release
5024e5dd7070Spatrick // operations), so we report them as non-scalar.
5025e5dd7070Spatrick if (T->isObjCLifetimeType()) {
5026e5dd7070Spatrick switch (T.getObjCLifetime()) {
5027e5dd7070Spatrick case Qualifiers::OCL_None:
5028e5dd7070Spatrick case Qualifiers::OCL_ExplicitNone:
5029e5dd7070Spatrick return true;
5030e5dd7070Spatrick
5031e5dd7070Spatrick case Qualifiers::OCL_Strong:
5032e5dd7070Spatrick case Qualifiers::OCL_Weak:
5033e5dd7070Spatrick case Qualifiers::OCL_Autoreleasing:
5034e5dd7070Spatrick return false;
5035e5dd7070Spatrick }
5036e5dd7070Spatrick }
5037e5dd7070Spatrick
5038e5dd7070Spatrick return T->isScalarType();
5039e5dd7070Spatrick case UTT_IsCompound:
5040e5dd7070Spatrick return T->isCompoundType();
5041e5dd7070Spatrick case UTT_IsMemberPointer:
5042e5dd7070Spatrick return T->isMemberPointerType();
5043e5dd7070Spatrick
5044e5dd7070Spatrick // Type trait expressions which correspond to the type property predicates
5045e5dd7070Spatrick // in C++0x [meta.unary.prop].
5046e5dd7070Spatrick case UTT_IsConst:
5047e5dd7070Spatrick return T.isConstQualified();
5048e5dd7070Spatrick case UTT_IsVolatile:
5049e5dd7070Spatrick return T.isVolatileQualified();
5050e5dd7070Spatrick case UTT_IsTrivial:
5051e5dd7070Spatrick return T.isTrivialType(C);
5052e5dd7070Spatrick case UTT_IsTriviallyCopyable:
5053e5dd7070Spatrick return T.isTriviallyCopyableType(C);
5054e5dd7070Spatrick case UTT_IsStandardLayout:
5055e5dd7070Spatrick return T->isStandardLayoutType();
5056e5dd7070Spatrick case UTT_IsPOD:
5057e5dd7070Spatrick return T.isPODType(C);
5058e5dd7070Spatrick case UTT_IsLiteral:
5059e5dd7070Spatrick return T->isLiteralType(C);
5060e5dd7070Spatrick case UTT_IsEmpty:
5061e5dd7070Spatrick if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
5062e5dd7070Spatrick return !RD->isUnion() && RD->isEmpty();
5063e5dd7070Spatrick return false;
5064e5dd7070Spatrick case UTT_IsPolymorphic:
5065e5dd7070Spatrick if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
5066e5dd7070Spatrick return !RD->isUnion() && RD->isPolymorphic();
5067e5dd7070Spatrick return false;
5068e5dd7070Spatrick case UTT_IsAbstract:
5069e5dd7070Spatrick if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
5070e5dd7070Spatrick return !RD->isUnion() && RD->isAbstract();
5071e5dd7070Spatrick return false;
5072e5dd7070Spatrick case UTT_IsAggregate:
5073e5dd7070Spatrick // Report vector extensions and complex types as aggregates because they
5074e5dd7070Spatrick // support aggregate initialization. GCC mirrors this behavior for vectors
5075e5dd7070Spatrick // but not _Complex.
5076e5dd7070Spatrick return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() ||
5077e5dd7070Spatrick T->isAnyComplexType();
5078e5dd7070Spatrick // __is_interface_class only returns true when CL is invoked in /CLR mode and
5079e5dd7070Spatrick // even then only when it is used with the 'interface struct ...' syntax
5080e5dd7070Spatrick // Clang doesn't support /CLR which makes this type trait moot.
5081e5dd7070Spatrick case UTT_IsInterfaceClass:
5082e5dd7070Spatrick return false;
5083e5dd7070Spatrick case UTT_IsFinal:
5084e5dd7070Spatrick case UTT_IsSealed:
5085e5dd7070Spatrick if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
5086e5dd7070Spatrick return RD->hasAttr<FinalAttr>();
5087e5dd7070Spatrick return false;
5088e5dd7070Spatrick case UTT_IsSigned:
5089e5dd7070Spatrick // Enum types should always return false.
5090e5dd7070Spatrick // Floating points should always return true.
5091a9ac8606Spatrick return T->isFloatingType() ||
5092a9ac8606Spatrick (T->isSignedIntegerType() && !T->isEnumeralType());
5093e5dd7070Spatrick case UTT_IsUnsigned:
5094a9ac8606Spatrick // Enum types should always return false.
5095a9ac8606Spatrick return T->isUnsignedIntegerType() && !T->isEnumeralType();
5096e5dd7070Spatrick
5097e5dd7070Spatrick // Type trait expressions which query classes regarding their construction,
5098e5dd7070Spatrick // destruction, and copying. Rather than being based directly on the
5099e5dd7070Spatrick // related type predicates in the standard, they are specified by both
5100e5dd7070Spatrick // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those
5101e5dd7070Spatrick // specifications.
5102e5dd7070Spatrick //
5103e5dd7070Spatrick // 1: http://gcc.gnu/.org/onlinedocs/gcc/Type-Traits.html
5104e5dd7070Spatrick // 2: http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
5105e5dd7070Spatrick //
5106e5dd7070Spatrick // Note that these builtins do not behave as documented in g++: if a class
5107e5dd7070Spatrick // has both a trivial and a non-trivial special member of a particular kind,
5108e5dd7070Spatrick // they return false! For now, we emulate this behavior.
5109e5dd7070Spatrick // FIXME: This appears to be a g++ bug: more complex cases reveal that it
5110e5dd7070Spatrick // does not correctly compute triviality in the presence of multiple special
5111e5dd7070Spatrick // members of the same kind. Revisit this once the g++ bug is fixed.
5112e5dd7070Spatrick case UTT_HasTrivialDefaultConstructor:
5113e5dd7070Spatrick // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
5114e5dd7070Spatrick // If __is_pod (type) is true then the trait is true, else if type is
5115e5dd7070Spatrick // a cv class or union type (or array thereof) with a trivial default
5116e5dd7070Spatrick // constructor ([class.ctor]) then the trait is true, else it is false.
5117e5dd7070Spatrick if (T.isPODType(C))
5118e5dd7070Spatrick return true;
5119e5dd7070Spatrick if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
5120e5dd7070Spatrick return RD->hasTrivialDefaultConstructor() &&
5121e5dd7070Spatrick !RD->hasNonTrivialDefaultConstructor();
5122e5dd7070Spatrick return false;
5123e5dd7070Spatrick case UTT_HasTrivialMoveConstructor:
5124e5dd7070Spatrick // This trait is implemented by MSVC 2012 and needed to parse the
5125e5dd7070Spatrick // standard library headers. Specifically this is used as the logic
5126e5dd7070Spatrick // behind std::is_trivially_move_constructible (20.9.4.3).
5127e5dd7070Spatrick if (T.isPODType(C))
5128e5dd7070Spatrick return true;
5129e5dd7070Spatrick if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
5130e5dd7070Spatrick return RD->hasTrivialMoveConstructor() && !RD->hasNonTrivialMoveConstructor();
5131e5dd7070Spatrick return false;
5132e5dd7070Spatrick case UTT_HasTrivialCopy:
5133e5dd7070Spatrick // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
5134e5dd7070Spatrick // If __is_pod (type) is true or type is a reference type then
5135e5dd7070Spatrick // the trait is true, else if type is a cv class or union type
5136e5dd7070Spatrick // with a trivial copy constructor ([class.copy]) then the trait
5137e5dd7070Spatrick // is true, else it is false.
5138e5dd7070Spatrick if (T.isPODType(C) || T->isReferenceType())
5139e5dd7070Spatrick return true;
5140e5dd7070Spatrick if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
5141e5dd7070Spatrick return RD->hasTrivialCopyConstructor() &&
5142e5dd7070Spatrick !RD->hasNonTrivialCopyConstructor();
5143e5dd7070Spatrick return false;
5144e5dd7070Spatrick case UTT_HasTrivialMoveAssign:
5145e5dd7070Spatrick // This trait is implemented by MSVC 2012 and needed to parse the
5146e5dd7070Spatrick // standard library headers. Specifically it is used as the logic
5147e5dd7070Spatrick // behind std::is_trivially_move_assignable (20.9.4.3)
5148e5dd7070Spatrick if (T.isPODType(C))
5149e5dd7070Spatrick return true;
5150e5dd7070Spatrick if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
5151e5dd7070Spatrick return RD->hasTrivialMoveAssignment() && !RD->hasNonTrivialMoveAssignment();
5152e5dd7070Spatrick return false;
5153e5dd7070Spatrick case UTT_HasTrivialAssign:
5154e5dd7070Spatrick // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
5155e5dd7070Spatrick // If type is const qualified or is a reference type then the
5156e5dd7070Spatrick // trait is false. Otherwise if __is_pod (type) is true then the
5157e5dd7070Spatrick // trait is true, else if type is a cv class or union type with
5158e5dd7070Spatrick // a trivial copy assignment ([class.copy]) then the trait is
5159e5dd7070Spatrick // true, else it is false.
5160e5dd7070Spatrick // Note: the const and reference restrictions are interesting,
5161e5dd7070Spatrick // given that const and reference members don't prevent a class
5162e5dd7070Spatrick // from having a trivial copy assignment operator (but do cause
5163e5dd7070Spatrick // errors if the copy assignment operator is actually used, q.v.
5164e5dd7070Spatrick // [class.copy]p12).
5165e5dd7070Spatrick
5166e5dd7070Spatrick if (T.isConstQualified())
5167e5dd7070Spatrick return false;
5168e5dd7070Spatrick if (T.isPODType(C))
5169e5dd7070Spatrick return true;
5170e5dd7070Spatrick if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
5171e5dd7070Spatrick return RD->hasTrivialCopyAssignment() &&
5172e5dd7070Spatrick !RD->hasNonTrivialCopyAssignment();
5173e5dd7070Spatrick return false;
5174e5dd7070Spatrick case UTT_IsDestructible:
5175e5dd7070Spatrick case UTT_IsTriviallyDestructible:
5176e5dd7070Spatrick case UTT_IsNothrowDestructible:
5177e5dd7070Spatrick // C++14 [meta.unary.prop]:
5178e5dd7070Spatrick // For reference types, is_destructible<T>::value is true.
5179e5dd7070Spatrick if (T->isReferenceType())
5180e5dd7070Spatrick return true;
5181e5dd7070Spatrick
5182e5dd7070Spatrick // Objective-C++ ARC: autorelease types don't require destruction.
5183e5dd7070Spatrick if (T->isObjCLifetimeType() &&
5184e5dd7070Spatrick T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
5185e5dd7070Spatrick return true;
5186e5dd7070Spatrick
5187e5dd7070Spatrick // C++14 [meta.unary.prop]:
5188e5dd7070Spatrick // For incomplete types and function types, is_destructible<T>::value is
5189e5dd7070Spatrick // false.
5190e5dd7070Spatrick if (T->isIncompleteType() || T->isFunctionType())
5191e5dd7070Spatrick return false;
5192e5dd7070Spatrick
5193e5dd7070Spatrick // A type that requires destruction (via a non-trivial destructor or ARC
5194e5dd7070Spatrick // lifetime semantics) is not trivially-destructible.
5195e5dd7070Spatrick if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())
5196e5dd7070Spatrick return false;
5197e5dd7070Spatrick
5198e5dd7070Spatrick // C++14 [meta.unary.prop]:
5199e5dd7070Spatrick // For object types and given U equal to remove_all_extents_t<T>, if the
5200e5dd7070Spatrick // expression std::declval<U&>().~U() is well-formed when treated as an
5201e5dd7070Spatrick // unevaluated operand (Clause 5), then is_destructible<T>::value is true
5202e5dd7070Spatrick if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
5203e5dd7070Spatrick CXXDestructorDecl *Destructor = Self.LookupDestructor(RD);
5204e5dd7070Spatrick if (!Destructor)
5205e5dd7070Spatrick return false;
5206e5dd7070Spatrick // C++14 [dcl.fct.def.delete]p2:
5207e5dd7070Spatrick // A program that refers to a deleted function implicitly or
5208e5dd7070Spatrick // explicitly, other than to declare it, is ill-formed.
5209e5dd7070Spatrick if (Destructor->isDeleted())
5210e5dd7070Spatrick return false;
5211e5dd7070Spatrick if (C.getLangOpts().AccessControl && Destructor->getAccess() != AS_public)
5212e5dd7070Spatrick return false;
5213e5dd7070Spatrick if (UTT == UTT_IsNothrowDestructible) {
5214ec727ea7Spatrick auto *CPT = Destructor->getType()->castAs<FunctionProtoType>();
5215e5dd7070Spatrick CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
5216e5dd7070Spatrick if (!CPT || !CPT->isNothrow())
5217e5dd7070Spatrick return false;
5218e5dd7070Spatrick }
5219e5dd7070Spatrick }
5220e5dd7070Spatrick return true;
5221e5dd7070Spatrick
5222e5dd7070Spatrick case UTT_HasTrivialDestructor:
5223e5dd7070Spatrick // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
5224e5dd7070Spatrick // If __is_pod (type) is true or type is a reference type
5225e5dd7070Spatrick // then the trait is true, else if type is a cv class or union
5226e5dd7070Spatrick // type (or array thereof) with a trivial destructor
5227e5dd7070Spatrick // ([class.dtor]) then the trait is true, else it is
5228e5dd7070Spatrick // false.
5229e5dd7070Spatrick if (T.isPODType(C) || T->isReferenceType())
5230e5dd7070Spatrick return true;
5231e5dd7070Spatrick
5232e5dd7070Spatrick // Objective-C++ ARC: autorelease types don't require destruction.
5233e5dd7070Spatrick if (T->isObjCLifetimeType() &&
5234e5dd7070Spatrick T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
5235e5dd7070Spatrick return true;
5236e5dd7070Spatrick
5237e5dd7070Spatrick if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
5238e5dd7070Spatrick return RD->hasTrivialDestructor();
5239e5dd7070Spatrick return false;
5240e5dd7070Spatrick // TODO: Propagate nothrowness for implicitly declared special members.
5241e5dd7070Spatrick case UTT_HasNothrowAssign:
5242e5dd7070Spatrick // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
5243e5dd7070Spatrick // If type is const qualified or is a reference type then the
5244e5dd7070Spatrick // trait is false. Otherwise if __has_trivial_assign (type)
5245e5dd7070Spatrick // is true then the trait is true, else if type is a cv class
5246e5dd7070Spatrick // or union type with copy assignment operators that are known
5247e5dd7070Spatrick // not to throw an exception then the trait is true, else it is
5248e5dd7070Spatrick // false.
5249e5dd7070Spatrick if (C.getBaseElementType(T).isConstQualified())
5250e5dd7070Spatrick return false;
5251e5dd7070Spatrick if (T->isReferenceType())
5252e5dd7070Spatrick return false;
5253e5dd7070Spatrick if (T.isPODType(C) || T->isObjCLifetimeType())
5254e5dd7070Spatrick return true;
5255e5dd7070Spatrick
5256e5dd7070Spatrick if (const RecordType *RT = T->getAs<RecordType>())
5257e5dd7070Spatrick return HasNoThrowOperator(RT, OO_Equal, Self, KeyLoc, C,
5258e5dd7070Spatrick &CXXRecordDecl::hasTrivialCopyAssignment,
5259e5dd7070Spatrick &CXXRecordDecl::hasNonTrivialCopyAssignment,
5260e5dd7070Spatrick &CXXMethodDecl::isCopyAssignmentOperator);
5261e5dd7070Spatrick return false;
5262e5dd7070Spatrick case UTT_HasNothrowMoveAssign:
5263e5dd7070Spatrick // This trait is implemented by MSVC 2012 and needed to parse the
5264e5dd7070Spatrick // standard library headers. Specifically this is used as the logic
5265e5dd7070Spatrick // behind std::is_nothrow_move_assignable (20.9.4.3).
5266e5dd7070Spatrick if (T.isPODType(C))
5267e5dd7070Spatrick return true;
5268e5dd7070Spatrick
5269e5dd7070Spatrick if (const RecordType *RT = C.getBaseElementType(T)->getAs<RecordType>())
5270e5dd7070Spatrick return HasNoThrowOperator(RT, OO_Equal, Self, KeyLoc, C,
5271e5dd7070Spatrick &CXXRecordDecl::hasTrivialMoveAssignment,
5272e5dd7070Spatrick &CXXRecordDecl::hasNonTrivialMoveAssignment,
5273e5dd7070Spatrick &CXXMethodDecl::isMoveAssignmentOperator);
5274e5dd7070Spatrick return false;
5275e5dd7070Spatrick case UTT_HasNothrowCopy:
5276e5dd7070Spatrick // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
5277e5dd7070Spatrick // If __has_trivial_copy (type) is true then the trait is true, else
5278e5dd7070Spatrick // if type is a cv class or union type with copy constructors that are
5279e5dd7070Spatrick // known not to throw an exception then the trait is true, else it is
5280e5dd7070Spatrick // false.
5281e5dd7070Spatrick if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType())
5282e5dd7070Spatrick return true;
5283e5dd7070Spatrick if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
5284e5dd7070Spatrick if (RD->hasTrivialCopyConstructor() &&
5285e5dd7070Spatrick !RD->hasNonTrivialCopyConstructor())
5286e5dd7070Spatrick return true;
5287e5dd7070Spatrick
5288e5dd7070Spatrick bool FoundConstructor = false;
5289e5dd7070Spatrick unsigned FoundTQs;
5290e5dd7070Spatrick for (const auto *ND : Self.LookupConstructors(RD)) {
5291e5dd7070Spatrick // A template constructor is never a copy constructor.
5292e5dd7070Spatrick // FIXME: However, it may actually be selected at the actual overload
5293e5dd7070Spatrick // resolution point.
5294e5dd7070Spatrick if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
5295e5dd7070Spatrick continue;
5296e5dd7070Spatrick // UsingDecl itself is not a constructor
5297e5dd7070Spatrick if (isa<UsingDecl>(ND))
5298e5dd7070Spatrick continue;
5299e5dd7070Spatrick auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
5300e5dd7070Spatrick if (Constructor->isCopyConstructor(FoundTQs)) {
5301e5dd7070Spatrick FoundConstructor = true;
5302ec727ea7Spatrick auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
5303e5dd7070Spatrick CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
5304e5dd7070Spatrick if (!CPT)
5305e5dd7070Spatrick return false;
5306e5dd7070Spatrick // TODO: check whether evaluating default arguments can throw.
5307e5dd7070Spatrick // For now, we'll be conservative and assume that they can throw.
5308e5dd7070Spatrick if (!CPT->isNothrow() || CPT->getNumParams() > 1)
5309e5dd7070Spatrick return false;
5310e5dd7070Spatrick }
5311e5dd7070Spatrick }
5312e5dd7070Spatrick
5313e5dd7070Spatrick return FoundConstructor;
5314e5dd7070Spatrick }
5315e5dd7070Spatrick return false;
5316e5dd7070Spatrick case UTT_HasNothrowConstructor:
5317e5dd7070Spatrick // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
5318e5dd7070Spatrick // If __has_trivial_constructor (type) is true then the trait is
5319e5dd7070Spatrick // true, else if type is a cv class or union type (or array
5320e5dd7070Spatrick // thereof) with a default constructor that is known not to
5321e5dd7070Spatrick // throw an exception then the trait is true, else it is false.
5322e5dd7070Spatrick if (T.isPODType(C) || T->isObjCLifetimeType())
5323e5dd7070Spatrick return true;
5324e5dd7070Spatrick if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
5325e5dd7070Spatrick if (RD->hasTrivialDefaultConstructor() &&
5326e5dd7070Spatrick !RD->hasNonTrivialDefaultConstructor())
5327e5dd7070Spatrick return true;
5328e5dd7070Spatrick
5329e5dd7070Spatrick bool FoundConstructor = false;
5330e5dd7070Spatrick for (const auto *ND : Self.LookupConstructors(RD)) {
5331e5dd7070Spatrick // FIXME: In C++0x, a constructor template can be a default constructor.
5332e5dd7070Spatrick if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
5333e5dd7070Spatrick continue;
5334e5dd7070Spatrick // UsingDecl itself is not a constructor
5335e5dd7070Spatrick if (isa<UsingDecl>(ND))
5336e5dd7070Spatrick continue;
5337e5dd7070Spatrick auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
5338e5dd7070Spatrick if (Constructor->isDefaultConstructor()) {
5339e5dd7070Spatrick FoundConstructor = true;
5340ec727ea7Spatrick auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
5341e5dd7070Spatrick CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
5342e5dd7070Spatrick if (!CPT)
5343e5dd7070Spatrick return false;
5344e5dd7070Spatrick // FIXME: check whether evaluating default arguments can throw.
5345e5dd7070Spatrick // For now, we'll be conservative and assume that they can throw.
5346e5dd7070Spatrick if (!CPT->isNothrow() || CPT->getNumParams() > 0)
5347e5dd7070Spatrick return false;
5348e5dd7070Spatrick }
5349e5dd7070Spatrick }
5350e5dd7070Spatrick return FoundConstructor;
5351e5dd7070Spatrick }
5352e5dd7070Spatrick return false;
5353e5dd7070Spatrick case UTT_HasVirtualDestructor:
5354e5dd7070Spatrick // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
5355e5dd7070Spatrick // If type is a class type with a virtual destructor ([class.dtor])
5356e5dd7070Spatrick // then the trait is true, else it is false.
5357e5dd7070Spatrick if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
5358e5dd7070Spatrick if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD))
5359e5dd7070Spatrick return Destructor->isVirtual();
5360e5dd7070Spatrick return false;
5361e5dd7070Spatrick
5362e5dd7070Spatrick // These type trait expressions are modeled on the specifications for the
5363e5dd7070Spatrick // Embarcadero C++0x type trait functions:
5364e5dd7070Spatrick // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
5365e5dd7070Spatrick case UTT_IsCompleteType:
5366e5dd7070Spatrick // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_):
5367e5dd7070Spatrick // Returns True if and only if T is a complete type at the point of the
5368e5dd7070Spatrick // function call.
5369e5dd7070Spatrick return !T->isIncompleteType();
5370e5dd7070Spatrick case UTT_HasUniqueObjectRepresentations:
5371e5dd7070Spatrick return C.hasUniqueObjectRepresentations(T);
5372*12c85518Srobert case UTT_IsTriviallyRelocatable:
5373*12c85518Srobert return T.isTriviallyRelocatableType(C);
5374*12c85518Srobert case UTT_IsReferenceable:
5375*12c85518Srobert return T.isReferenceable();
5376e5dd7070Spatrick }
5377e5dd7070Spatrick }
5378e5dd7070Spatrick
5379e5dd7070Spatrick static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
5380e5dd7070Spatrick QualType RhsT, SourceLocation KeyLoc);
5381e5dd7070Spatrick
evaluateTypeTrait(Sema & S,TypeTrait Kind,SourceLocation KWLoc,ArrayRef<TypeSourceInfo * > Args,SourceLocation RParenLoc)5382e5dd7070Spatrick static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
5383e5dd7070Spatrick ArrayRef<TypeSourceInfo *> Args,
5384e5dd7070Spatrick SourceLocation RParenLoc) {
5385e5dd7070Spatrick if (Kind <= UTT_Last)
5386e5dd7070Spatrick return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]->getType());
5387e5dd7070Spatrick
5388e5dd7070Spatrick // Evaluate BTT_ReferenceBindsToTemporary alongside the IsConstructible
5389e5dd7070Spatrick // traits to avoid duplication.
5390e5dd7070Spatrick if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary)
5391e5dd7070Spatrick return EvaluateBinaryTypeTrait(S, Kind, Args[0]->getType(),
5392e5dd7070Spatrick Args[1]->getType(), RParenLoc);
5393e5dd7070Spatrick
5394e5dd7070Spatrick switch (Kind) {
5395e5dd7070Spatrick case clang::BTT_ReferenceBindsToTemporary:
5396e5dd7070Spatrick case clang::TT_IsConstructible:
5397e5dd7070Spatrick case clang::TT_IsNothrowConstructible:
5398e5dd7070Spatrick case clang::TT_IsTriviallyConstructible: {
5399e5dd7070Spatrick // C++11 [meta.unary.prop]:
5400e5dd7070Spatrick // is_trivially_constructible is defined as:
5401e5dd7070Spatrick //
5402e5dd7070Spatrick // is_constructible<T, Args...>::value is true and the variable
5403e5dd7070Spatrick // definition for is_constructible, as defined below, is known to call
5404e5dd7070Spatrick // no operation that is not trivial.
5405e5dd7070Spatrick //
5406e5dd7070Spatrick // The predicate condition for a template specialization
5407e5dd7070Spatrick // is_constructible<T, Args...> shall be satisfied if and only if the
5408e5dd7070Spatrick // following variable definition would be well-formed for some invented
5409e5dd7070Spatrick // variable t:
5410e5dd7070Spatrick //
5411e5dd7070Spatrick // T t(create<Args>()...);
5412e5dd7070Spatrick assert(!Args.empty());
5413e5dd7070Spatrick
5414e5dd7070Spatrick // Precondition: T and all types in the parameter pack Args shall be
5415e5dd7070Spatrick // complete types, (possibly cv-qualified) void, or arrays of
5416e5dd7070Spatrick // unknown bound.
5417e5dd7070Spatrick for (const auto *TSI : Args) {
5418e5dd7070Spatrick QualType ArgTy = TSI->getType();
5419e5dd7070Spatrick if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
5420e5dd7070Spatrick continue;
5421e5dd7070Spatrick
5422e5dd7070Spatrick if (S.RequireCompleteType(KWLoc, ArgTy,
5423e5dd7070Spatrick diag::err_incomplete_type_used_in_type_trait_expr))
5424e5dd7070Spatrick return false;
5425e5dd7070Spatrick }
5426e5dd7070Spatrick
5427e5dd7070Spatrick // Make sure the first argument is not incomplete nor a function type.
5428e5dd7070Spatrick QualType T = Args[0]->getType();
5429e5dd7070Spatrick if (T->isIncompleteType() || T->isFunctionType())
5430e5dd7070Spatrick return false;
5431e5dd7070Spatrick
5432e5dd7070Spatrick // Make sure the first argument is not an abstract type.
5433e5dd7070Spatrick CXXRecordDecl *RD = T->getAsCXXRecordDecl();
5434e5dd7070Spatrick if (RD && RD->isAbstract())
5435e5dd7070Spatrick return false;
5436e5dd7070Spatrick
5437ec727ea7Spatrick llvm::BumpPtrAllocator OpaqueExprAllocator;
5438e5dd7070Spatrick SmallVector<Expr *, 2> ArgExprs;
5439e5dd7070Spatrick ArgExprs.reserve(Args.size() - 1);
5440e5dd7070Spatrick for (unsigned I = 1, N = Args.size(); I != N; ++I) {
5441e5dd7070Spatrick QualType ArgTy = Args[I]->getType();
5442e5dd7070Spatrick if (ArgTy->isObjectType() || ArgTy->isFunctionType())
5443e5dd7070Spatrick ArgTy = S.Context.getRValueReferenceType(ArgTy);
5444ec727ea7Spatrick ArgExprs.push_back(
5445ec727ea7Spatrick new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
5446e5dd7070Spatrick OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),
5447e5dd7070Spatrick ArgTy.getNonLValueExprType(S.Context),
5448e5dd7070Spatrick Expr::getValueKindForType(ArgTy)));
5449e5dd7070Spatrick }
5450e5dd7070Spatrick
5451e5dd7070Spatrick // Perform the initialization in an unevaluated context within a SFINAE
5452e5dd7070Spatrick // trap at translation unit scope.
5453e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
5454e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::Unevaluated);
5455e5dd7070Spatrick Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true);
5456e5dd7070Spatrick Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
5457*12c85518Srobert InitializedEntity To(
5458*12c85518Srobert InitializedEntity::InitializeTemporary(S.Context, Args[0]));
5459e5dd7070Spatrick InitializationKind InitKind(InitializationKind::CreateDirect(KWLoc, KWLoc,
5460e5dd7070Spatrick RParenLoc));
5461e5dd7070Spatrick InitializationSequence Init(S, To, InitKind, ArgExprs);
5462e5dd7070Spatrick if (Init.Failed())
5463e5dd7070Spatrick return false;
5464e5dd7070Spatrick
5465e5dd7070Spatrick ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
5466e5dd7070Spatrick if (Result.isInvalid() || SFINAE.hasErrorOccurred())
5467e5dd7070Spatrick return false;
5468e5dd7070Spatrick
5469e5dd7070Spatrick if (Kind == clang::TT_IsConstructible)
5470e5dd7070Spatrick return true;
5471e5dd7070Spatrick
5472e5dd7070Spatrick if (Kind == clang::BTT_ReferenceBindsToTemporary) {
5473e5dd7070Spatrick if (!T->isReferenceType())
5474e5dd7070Spatrick return false;
5475e5dd7070Spatrick
5476e5dd7070Spatrick return !Init.isDirectReferenceBinding();
5477e5dd7070Spatrick }
5478e5dd7070Spatrick
5479e5dd7070Spatrick if (Kind == clang::TT_IsNothrowConstructible)
5480e5dd7070Spatrick return S.canThrow(Result.get()) == CT_Cannot;
5481e5dd7070Spatrick
5482e5dd7070Spatrick if (Kind == clang::TT_IsTriviallyConstructible) {
5483e5dd7070Spatrick // Under Objective-C ARC and Weak, if the destination has non-trivial
5484e5dd7070Spatrick // Objective-C lifetime, this is a non-trivial construction.
5485e5dd7070Spatrick if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
5486e5dd7070Spatrick return false;
5487e5dd7070Spatrick
5488e5dd7070Spatrick // The initialization succeeded; now make sure there are no non-trivial
5489e5dd7070Spatrick // calls.
5490e5dd7070Spatrick return !Result.get()->hasNonTrivialCall(S.Context);
5491e5dd7070Spatrick }
5492e5dd7070Spatrick
5493e5dd7070Spatrick llvm_unreachable("unhandled type trait");
5494e5dd7070Spatrick return false;
5495e5dd7070Spatrick }
5496e5dd7070Spatrick default: llvm_unreachable("not a TT");
5497e5dd7070Spatrick }
5498e5dd7070Spatrick
5499e5dd7070Spatrick return false;
5500e5dd7070Spatrick }
5501e5dd7070Spatrick
5502*12c85518Srobert namespace {
DiagnoseBuiltinDeprecation(Sema & S,TypeTrait Kind,SourceLocation KWLoc)5503*12c85518Srobert void DiagnoseBuiltinDeprecation(Sema& S, TypeTrait Kind,
5504*12c85518Srobert SourceLocation KWLoc) {
5505*12c85518Srobert TypeTrait Replacement;
5506*12c85518Srobert switch (Kind) {
5507*12c85518Srobert case UTT_HasNothrowAssign:
5508*12c85518Srobert case UTT_HasNothrowMoveAssign:
5509*12c85518Srobert Replacement = BTT_IsNothrowAssignable;
5510*12c85518Srobert break;
5511*12c85518Srobert case UTT_HasNothrowCopy:
5512*12c85518Srobert case UTT_HasNothrowConstructor:
5513*12c85518Srobert Replacement = TT_IsNothrowConstructible;
5514*12c85518Srobert break;
5515*12c85518Srobert case UTT_HasTrivialAssign:
5516*12c85518Srobert case UTT_HasTrivialMoveAssign:
5517*12c85518Srobert Replacement = BTT_IsTriviallyAssignable;
5518*12c85518Srobert break;
5519*12c85518Srobert case UTT_HasTrivialCopy:
5520*12c85518Srobert Replacement = UTT_IsTriviallyCopyable;
5521*12c85518Srobert break;
5522*12c85518Srobert case UTT_HasTrivialDefaultConstructor:
5523*12c85518Srobert case UTT_HasTrivialMoveConstructor:
5524*12c85518Srobert Replacement = TT_IsTriviallyConstructible;
5525*12c85518Srobert break;
5526*12c85518Srobert case UTT_HasTrivialDestructor:
5527*12c85518Srobert Replacement = UTT_IsTriviallyDestructible;
5528*12c85518Srobert break;
5529*12c85518Srobert default:
5530*12c85518Srobert return;
5531*12c85518Srobert }
5532*12c85518Srobert S.Diag(KWLoc, diag::warn_deprecated_builtin)
5533*12c85518Srobert << getTraitSpelling(Kind) << getTraitSpelling(Replacement);
5534*12c85518Srobert }
5535*12c85518Srobert }
5536*12c85518Srobert
CheckTypeTraitArity(unsigned Arity,SourceLocation Loc,size_t N)5537*12c85518Srobert bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {
5538*12c85518Srobert if (Arity && N != Arity) {
5539*12c85518Srobert Diag(Loc, diag::err_type_trait_arity)
5540*12c85518Srobert << Arity << 0 << (Arity > 1) << (int)N << SourceRange(Loc);
5541*12c85518Srobert return false;
5542*12c85518Srobert }
5543*12c85518Srobert
5544*12c85518Srobert if (!Arity && N == 0) {
5545*12c85518Srobert Diag(Loc, diag::err_type_trait_arity)
5546*12c85518Srobert << 1 << 1 << 1 << (int)N << SourceRange(Loc);
5547*12c85518Srobert return false;
5548*12c85518Srobert }
5549*12c85518Srobert return true;
5550*12c85518Srobert }
5551*12c85518Srobert
BuildTypeTrait(TypeTrait Kind,SourceLocation KWLoc,ArrayRef<TypeSourceInfo * > Args,SourceLocation RParenLoc)5552e5dd7070Spatrick ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
5553e5dd7070Spatrick ArrayRef<TypeSourceInfo *> Args,
5554e5dd7070Spatrick SourceLocation RParenLoc) {
5555*12c85518Srobert if (!CheckTypeTraitArity(getTypeTraitArity(Kind), KWLoc, Args.size()))
5556*12c85518Srobert return ExprError();
5557e5dd7070Spatrick QualType ResultType = Context.getLogicalOperationType();
5558e5dd7070Spatrick
5559e5dd7070Spatrick if (Kind <= UTT_Last && !CheckUnaryTypeTraitTypeCompleteness(
5560e5dd7070Spatrick *this, Kind, KWLoc, Args[0]->getType()))
5561e5dd7070Spatrick return ExprError();
5562e5dd7070Spatrick
5563*12c85518Srobert DiagnoseBuiltinDeprecation(*this, Kind, KWLoc);
5564*12c85518Srobert
5565e5dd7070Spatrick bool Dependent = false;
5566e5dd7070Spatrick for (unsigned I = 0, N = Args.size(); I != N; ++I) {
5567e5dd7070Spatrick if (Args[I]->getType()->isDependentType()) {
5568e5dd7070Spatrick Dependent = true;
5569e5dd7070Spatrick break;
5570e5dd7070Spatrick }
5571e5dd7070Spatrick }
5572e5dd7070Spatrick
5573e5dd7070Spatrick bool Result = false;
5574e5dd7070Spatrick if (!Dependent)
5575e5dd7070Spatrick Result = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc);
5576e5dd7070Spatrick
5577e5dd7070Spatrick return TypeTraitExpr::Create(Context, ResultType, KWLoc, Kind, Args,
5578e5dd7070Spatrick RParenLoc, Result);
5579e5dd7070Spatrick }
5580e5dd7070Spatrick
ActOnTypeTrait(TypeTrait Kind,SourceLocation KWLoc,ArrayRef<ParsedType> Args,SourceLocation RParenLoc)5581e5dd7070Spatrick ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
5582e5dd7070Spatrick ArrayRef<ParsedType> Args,
5583e5dd7070Spatrick SourceLocation RParenLoc) {
5584e5dd7070Spatrick SmallVector<TypeSourceInfo *, 4> ConvertedArgs;
5585e5dd7070Spatrick ConvertedArgs.reserve(Args.size());
5586e5dd7070Spatrick
5587e5dd7070Spatrick for (unsigned I = 0, N = Args.size(); I != N; ++I) {
5588e5dd7070Spatrick TypeSourceInfo *TInfo;
5589e5dd7070Spatrick QualType T = GetTypeFromParser(Args[I], &TInfo);
5590e5dd7070Spatrick if (!TInfo)
5591e5dd7070Spatrick TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);
5592e5dd7070Spatrick
5593e5dd7070Spatrick ConvertedArgs.push_back(TInfo);
5594e5dd7070Spatrick }
5595e5dd7070Spatrick
5596e5dd7070Spatrick return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
5597e5dd7070Spatrick }
5598e5dd7070Spatrick
EvaluateBinaryTypeTrait(Sema & Self,TypeTrait BTT,QualType LhsT,QualType RhsT,SourceLocation KeyLoc)5599e5dd7070Spatrick static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
5600e5dd7070Spatrick QualType RhsT, SourceLocation KeyLoc) {
5601e5dd7070Spatrick assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
5602e5dd7070Spatrick "Cannot evaluate traits of dependent types");
5603e5dd7070Spatrick
5604e5dd7070Spatrick switch(BTT) {
5605e5dd7070Spatrick case BTT_IsBaseOf: {
5606e5dd7070Spatrick // C++0x [meta.rel]p2
5607e5dd7070Spatrick // Base is a base class of Derived without regard to cv-qualifiers or
5608e5dd7070Spatrick // Base and Derived are not unions and name the same class type without
5609e5dd7070Spatrick // regard to cv-qualifiers.
5610e5dd7070Spatrick
5611e5dd7070Spatrick const RecordType *lhsRecord = LhsT->getAs<RecordType>();
5612e5dd7070Spatrick const RecordType *rhsRecord = RhsT->getAs<RecordType>();
5613e5dd7070Spatrick if (!rhsRecord || !lhsRecord) {
5614e5dd7070Spatrick const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();
5615e5dd7070Spatrick const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();
5616e5dd7070Spatrick if (!LHSObjTy || !RHSObjTy)
5617e5dd7070Spatrick return false;
5618e5dd7070Spatrick
5619e5dd7070Spatrick ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
5620e5dd7070Spatrick ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
5621e5dd7070Spatrick if (!BaseInterface || !DerivedInterface)
5622e5dd7070Spatrick return false;
5623e5dd7070Spatrick
5624e5dd7070Spatrick if (Self.RequireCompleteType(
5625e5dd7070Spatrick KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr))
5626e5dd7070Spatrick return false;
5627e5dd7070Spatrick
5628e5dd7070Spatrick return BaseInterface->isSuperClassOf(DerivedInterface);
5629e5dd7070Spatrick }
5630e5dd7070Spatrick
5631e5dd7070Spatrick assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT)
5632e5dd7070Spatrick == (lhsRecord == rhsRecord));
5633e5dd7070Spatrick
5634e5dd7070Spatrick // Unions are never base classes, and never have base classes.
5635e5dd7070Spatrick // It doesn't matter if they are complete or not. See PR#41843
5636e5dd7070Spatrick if (lhsRecord && lhsRecord->getDecl()->isUnion())
5637e5dd7070Spatrick return false;
5638e5dd7070Spatrick if (rhsRecord && rhsRecord->getDecl()->isUnion())
5639e5dd7070Spatrick return false;
5640e5dd7070Spatrick
5641e5dd7070Spatrick if (lhsRecord == rhsRecord)
5642e5dd7070Spatrick return true;
5643e5dd7070Spatrick
5644e5dd7070Spatrick // C++0x [meta.rel]p2:
5645e5dd7070Spatrick // If Base and Derived are class types and are different types
5646e5dd7070Spatrick // (ignoring possible cv-qualifiers) then Derived shall be a
5647e5dd7070Spatrick // complete type.
5648e5dd7070Spatrick if (Self.RequireCompleteType(KeyLoc, RhsT,
5649e5dd7070Spatrick diag::err_incomplete_type_used_in_type_trait_expr))
5650e5dd7070Spatrick return false;
5651e5dd7070Spatrick
5652e5dd7070Spatrick return cast<CXXRecordDecl>(rhsRecord->getDecl())
5653e5dd7070Spatrick ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));
5654e5dd7070Spatrick }
5655e5dd7070Spatrick case BTT_IsSame:
5656e5dd7070Spatrick return Self.Context.hasSameType(LhsT, RhsT);
5657e5dd7070Spatrick case BTT_TypeCompatible: {
5658e5dd7070Spatrick // GCC ignores cv-qualifiers on arrays for this builtin.
5659e5dd7070Spatrick Qualifiers LhsQuals, RhsQuals;
5660e5dd7070Spatrick QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
5661e5dd7070Spatrick QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
5662e5dd7070Spatrick return Self.Context.typesAreCompatible(Lhs, Rhs);
5663e5dd7070Spatrick }
5664e5dd7070Spatrick case BTT_IsConvertible:
5665e5dd7070Spatrick case BTT_IsConvertibleTo: {
5666e5dd7070Spatrick // C++0x [meta.rel]p4:
5667e5dd7070Spatrick // Given the following function prototype:
5668e5dd7070Spatrick //
5669e5dd7070Spatrick // template <class T>
5670e5dd7070Spatrick // typename add_rvalue_reference<T>::type create();
5671e5dd7070Spatrick //
5672e5dd7070Spatrick // the predicate condition for a template specialization
5673e5dd7070Spatrick // is_convertible<From, To> shall be satisfied if and only if
5674e5dd7070Spatrick // the return expression in the following code would be
5675e5dd7070Spatrick // well-formed, including any implicit conversions to the return
5676e5dd7070Spatrick // type of the function:
5677e5dd7070Spatrick //
5678e5dd7070Spatrick // To test() {
5679e5dd7070Spatrick // return create<From>();
5680e5dd7070Spatrick // }
5681e5dd7070Spatrick //
5682e5dd7070Spatrick // Access checking is performed as if in a context unrelated to To and
5683e5dd7070Spatrick // From. Only the validity of the immediate context of the expression
5684e5dd7070Spatrick // of the return-statement (including conversions to the return type)
5685e5dd7070Spatrick // is considered.
5686e5dd7070Spatrick //
5687e5dd7070Spatrick // We model the initialization as a copy-initialization of a temporary
5688e5dd7070Spatrick // of the appropriate type, which for this expression is identical to the
5689e5dd7070Spatrick // return statement (since NRVO doesn't apply).
5690e5dd7070Spatrick
5691e5dd7070Spatrick // Functions aren't allowed to return function or array types.
5692e5dd7070Spatrick if (RhsT->isFunctionType() || RhsT->isArrayType())
5693e5dd7070Spatrick return false;
5694e5dd7070Spatrick
5695e5dd7070Spatrick // A return statement in a void function must have void type.
5696e5dd7070Spatrick if (RhsT->isVoidType())
5697e5dd7070Spatrick return LhsT->isVoidType();
5698e5dd7070Spatrick
5699e5dd7070Spatrick // A function definition requires a complete, non-abstract return type.
5700e5dd7070Spatrick if (!Self.isCompleteType(KeyLoc, RhsT) || Self.isAbstractType(KeyLoc, RhsT))
5701e5dd7070Spatrick return false;
5702e5dd7070Spatrick
5703e5dd7070Spatrick // Compute the result of add_rvalue_reference.
5704e5dd7070Spatrick if (LhsT->isObjectType() || LhsT->isFunctionType())
5705e5dd7070Spatrick LhsT = Self.Context.getRValueReferenceType(LhsT);
5706e5dd7070Spatrick
5707e5dd7070Spatrick // Build a fake source and destination for initialization.
5708e5dd7070Spatrick InitializedEntity To(InitializedEntity::InitializeTemporary(RhsT));
5709e5dd7070Spatrick OpaqueValueExpr From(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
5710e5dd7070Spatrick Expr::getValueKindForType(LhsT));
5711e5dd7070Spatrick Expr *FromPtr = &From;
5712e5dd7070Spatrick InitializationKind Kind(InitializationKind::CreateCopy(KeyLoc,
5713e5dd7070Spatrick SourceLocation()));
5714e5dd7070Spatrick
5715e5dd7070Spatrick // Perform the initialization in an unevaluated context within a SFINAE
5716e5dd7070Spatrick // trap at translation unit scope.
5717e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
5718e5dd7070Spatrick Self, Sema::ExpressionEvaluationContext::Unevaluated);
5719e5dd7070Spatrick Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true);
5720e5dd7070Spatrick Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
5721e5dd7070Spatrick InitializationSequence Init(Self, To, Kind, FromPtr);
5722e5dd7070Spatrick if (Init.Failed())
5723e5dd7070Spatrick return false;
5724e5dd7070Spatrick
5725e5dd7070Spatrick ExprResult Result = Init.Perform(Self, To, Kind, FromPtr);
5726e5dd7070Spatrick return !Result.isInvalid() && !SFINAE.hasErrorOccurred();
5727e5dd7070Spatrick }
5728e5dd7070Spatrick
5729e5dd7070Spatrick case BTT_IsAssignable:
5730e5dd7070Spatrick case BTT_IsNothrowAssignable:
5731e5dd7070Spatrick case BTT_IsTriviallyAssignable: {
5732e5dd7070Spatrick // C++11 [meta.unary.prop]p3:
5733e5dd7070Spatrick // is_trivially_assignable is defined as:
5734e5dd7070Spatrick // is_assignable<T, U>::value is true and the assignment, as defined by
5735e5dd7070Spatrick // is_assignable, is known to call no operation that is not trivial
5736e5dd7070Spatrick //
5737e5dd7070Spatrick // is_assignable is defined as:
5738e5dd7070Spatrick // The expression declval<T>() = declval<U>() is well-formed when
5739e5dd7070Spatrick // treated as an unevaluated operand (Clause 5).
5740e5dd7070Spatrick //
5741e5dd7070Spatrick // For both, T and U shall be complete types, (possibly cv-qualified)
5742e5dd7070Spatrick // void, or arrays of unknown bound.
5743e5dd7070Spatrick if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
5744e5dd7070Spatrick Self.RequireCompleteType(KeyLoc, LhsT,
5745e5dd7070Spatrick diag::err_incomplete_type_used_in_type_trait_expr))
5746e5dd7070Spatrick return false;
5747e5dd7070Spatrick if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
5748e5dd7070Spatrick Self.RequireCompleteType(KeyLoc, RhsT,
5749e5dd7070Spatrick diag::err_incomplete_type_used_in_type_trait_expr))
5750e5dd7070Spatrick return false;
5751e5dd7070Spatrick
5752e5dd7070Spatrick // cv void is never assignable.
5753e5dd7070Spatrick if (LhsT->isVoidType() || RhsT->isVoidType())
5754e5dd7070Spatrick return false;
5755e5dd7070Spatrick
5756e5dd7070Spatrick // Build expressions that emulate the effect of declval<T>() and
5757e5dd7070Spatrick // declval<U>().
5758e5dd7070Spatrick if (LhsT->isObjectType() || LhsT->isFunctionType())
5759e5dd7070Spatrick LhsT = Self.Context.getRValueReferenceType(LhsT);
5760e5dd7070Spatrick if (RhsT->isObjectType() || RhsT->isFunctionType())
5761e5dd7070Spatrick RhsT = Self.Context.getRValueReferenceType(RhsT);
5762e5dd7070Spatrick OpaqueValueExpr Lhs(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
5763e5dd7070Spatrick Expr::getValueKindForType(LhsT));
5764e5dd7070Spatrick OpaqueValueExpr Rhs(KeyLoc, RhsT.getNonLValueExprType(Self.Context),
5765e5dd7070Spatrick Expr::getValueKindForType(RhsT));
5766e5dd7070Spatrick
5767e5dd7070Spatrick // Attempt the assignment in an unevaluated context within a SFINAE
5768e5dd7070Spatrick // trap at translation unit scope.
5769e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
5770e5dd7070Spatrick Self, Sema::ExpressionEvaluationContext::Unevaluated);
5771e5dd7070Spatrick Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true);
5772e5dd7070Spatrick Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
5773e5dd7070Spatrick ExprResult Result = Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs,
5774e5dd7070Spatrick &Rhs);
5775e5dd7070Spatrick if (Result.isInvalid())
5776e5dd7070Spatrick return false;
5777e5dd7070Spatrick
5778e5dd7070Spatrick // Treat the assignment as unused for the purpose of -Wdeprecated-volatile.
5779e5dd7070Spatrick Self.CheckUnusedVolatileAssignment(Result.get());
5780e5dd7070Spatrick
5781e5dd7070Spatrick if (SFINAE.hasErrorOccurred())
5782e5dd7070Spatrick return false;
5783e5dd7070Spatrick
5784e5dd7070Spatrick if (BTT == BTT_IsAssignable)
5785e5dd7070Spatrick return true;
5786e5dd7070Spatrick
5787e5dd7070Spatrick if (BTT == BTT_IsNothrowAssignable)
5788e5dd7070Spatrick return Self.canThrow(Result.get()) == CT_Cannot;
5789e5dd7070Spatrick
5790e5dd7070Spatrick if (BTT == BTT_IsTriviallyAssignable) {
5791e5dd7070Spatrick // Under Objective-C ARC and Weak, if the destination has non-trivial
5792e5dd7070Spatrick // Objective-C lifetime, this is a non-trivial assignment.
5793e5dd7070Spatrick if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime())
5794e5dd7070Spatrick return false;
5795e5dd7070Spatrick
5796e5dd7070Spatrick return !Result.get()->hasNonTrivialCall(Self.Context);
5797e5dd7070Spatrick }
5798e5dd7070Spatrick
5799e5dd7070Spatrick llvm_unreachable("unhandled type trait");
5800e5dd7070Spatrick return false;
5801e5dd7070Spatrick }
5802e5dd7070Spatrick default: llvm_unreachable("not a BTT");
5803e5dd7070Spatrick }
5804e5dd7070Spatrick llvm_unreachable("Unknown type trait or not implemented");
5805e5dd7070Spatrick }
5806e5dd7070Spatrick
ActOnArrayTypeTrait(ArrayTypeTrait ATT,SourceLocation KWLoc,ParsedType Ty,Expr * DimExpr,SourceLocation RParen)5807e5dd7070Spatrick ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT,
5808e5dd7070Spatrick SourceLocation KWLoc,
5809e5dd7070Spatrick ParsedType Ty,
5810e5dd7070Spatrick Expr* DimExpr,
5811e5dd7070Spatrick SourceLocation RParen) {
5812e5dd7070Spatrick TypeSourceInfo *TSInfo;
5813e5dd7070Spatrick QualType T = GetTypeFromParser(Ty, &TSInfo);
5814e5dd7070Spatrick if (!TSInfo)
5815e5dd7070Spatrick TSInfo = Context.getTrivialTypeSourceInfo(T);
5816e5dd7070Spatrick
5817e5dd7070Spatrick return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
5818e5dd7070Spatrick }
5819e5dd7070Spatrick
EvaluateArrayTypeTrait(Sema & Self,ArrayTypeTrait ATT,QualType T,Expr * DimExpr,SourceLocation KeyLoc)5820e5dd7070Spatrick static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT,
5821e5dd7070Spatrick QualType T, Expr *DimExpr,
5822e5dd7070Spatrick SourceLocation KeyLoc) {
5823e5dd7070Spatrick assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
5824e5dd7070Spatrick
5825e5dd7070Spatrick switch(ATT) {
5826e5dd7070Spatrick case ATT_ArrayRank:
5827e5dd7070Spatrick if (T->isArrayType()) {
5828e5dd7070Spatrick unsigned Dim = 0;
5829e5dd7070Spatrick while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
5830e5dd7070Spatrick ++Dim;
5831e5dd7070Spatrick T = AT->getElementType();
5832e5dd7070Spatrick }
5833e5dd7070Spatrick return Dim;
5834e5dd7070Spatrick }
5835e5dd7070Spatrick return 0;
5836e5dd7070Spatrick
5837e5dd7070Spatrick case ATT_ArrayExtent: {
5838e5dd7070Spatrick llvm::APSInt Value;
5839e5dd7070Spatrick uint64_t Dim;
5840a9ac8606Spatrick if (Self.VerifyIntegerConstantExpression(
5841a9ac8606Spatrick DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)
5842a9ac8606Spatrick .isInvalid())
5843e5dd7070Spatrick return 0;
5844e5dd7070Spatrick if (Value.isSigned() && Value.isNegative()) {
5845e5dd7070Spatrick Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
5846e5dd7070Spatrick << DimExpr->getSourceRange();
5847e5dd7070Spatrick return 0;
5848e5dd7070Spatrick }
5849e5dd7070Spatrick Dim = Value.getLimitedValue();
5850e5dd7070Spatrick
5851e5dd7070Spatrick if (T->isArrayType()) {
5852e5dd7070Spatrick unsigned D = 0;
5853e5dd7070Spatrick bool Matched = false;
5854e5dd7070Spatrick while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
5855e5dd7070Spatrick if (Dim == D) {
5856e5dd7070Spatrick Matched = true;
5857e5dd7070Spatrick break;
5858e5dd7070Spatrick }
5859e5dd7070Spatrick ++D;
5860e5dd7070Spatrick T = AT->getElementType();
5861e5dd7070Spatrick }
5862e5dd7070Spatrick
5863e5dd7070Spatrick if (Matched && T->isArrayType()) {
5864e5dd7070Spatrick if (const ConstantArrayType *CAT = Self.Context.getAsConstantArrayType(T))
5865e5dd7070Spatrick return CAT->getSize().getLimitedValue();
5866e5dd7070Spatrick }
5867e5dd7070Spatrick }
5868e5dd7070Spatrick return 0;
5869e5dd7070Spatrick }
5870e5dd7070Spatrick }
5871e5dd7070Spatrick llvm_unreachable("Unknown type trait or not implemented");
5872e5dd7070Spatrick }
5873e5dd7070Spatrick
BuildArrayTypeTrait(ArrayTypeTrait ATT,SourceLocation KWLoc,TypeSourceInfo * TSInfo,Expr * DimExpr,SourceLocation RParen)5874e5dd7070Spatrick ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT,
5875e5dd7070Spatrick SourceLocation KWLoc,
5876e5dd7070Spatrick TypeSourceInfo *TSInfo,
5877e5dd7070Spatrick Expr* DimExpr,
5878e5dd7070Spatrick SourceLocation RParen) {
5879e5dd7070Spatrick QualType T = TSInfo->getType();
5880e5dd7070Spatrick
5881e5dd7070Spatrick // FIXME: This should likely be tracked as an APInt to remove any host
5882e5dd7070Spatrick // assumptions about the width of size_t on the target.
5883e5dd7070Spatrick uint64_t Value = 0;
5884e5dd7070Spatrick if (!T->isDependentType())
5885e5dd7070Spatrick Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);
5886e5dd7070Spatrick
5887e5dd7070Spatrick // While the specification for these traits from the Embarcadero C++
5888e5dd7070Spatrick // compiler's documentation says the return type is 'unsigned int', Clang
5889e5dd7070Spatrick // returns 'size_t'. On Windows, the primary platform for the Embarcadero
5890e5dd7070Spatrick // compiler, there is no difference. On several other platforms this is an
5891e5dd7070Spatrick // important distinction.
5892e5dd7070Spatrick return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
5893e5dd7070Spatrick RParen, Context.getSizeType());
5894e5dd7070Spatrick }
5895e5dd7070Spatrick
ActOnExpressionTrait(ExpressionTrait ET,SourceLocation KWLoc,Expr * Queried,SourceLocation RParen)5896e5dd7070Spatrick ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET,
5897e5dd7070Spatrick SourceLocation KWLoc,
5898e5dd7070Spatrick Expr *Queried,
5899e5dd7070Spatrick SourceLocation RParen) {
5900e5dd7070Spatrick // If error parsing the expression, ignore.
5901e5dd7070Spatrick if (!Queried)
5902e5dd7070Spatrick return ExprError();
5903e5dd7070Spatrick
5904e5dd7070Spatrick ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen);
5905e5dd7070Spatrick
5906e5dd7070Spatrick return Result;
5907e5dd7070Spatrick }
5908e5dd7070Spatrick
EvaluateExpressionTrait(ExpressionTrait ET,Expr * E)5909e5dd7070Spatrick static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E) {
5910e5dd7070Spatrick switch (ET) {
5911e5dd7070Spatrick case ET_IsLValueExpr: return E->isLValue();
5912a9ac8606Spatrick case ET_IsRValueExpr:
5913a9ac8606Spatrick return E->isPRValue();
5914e5dd7070Spatrick }
5915e5dd7070Spatrick llvm_unreachable("Expression trait not covered by switch");
5916e5dd7070Spatrick }
5917e5dd7070Spatrick
BuildExpressionTrait(ExpressionTrait ET,SourceLocation KWLoc,Expr * Queried,SourceLocation RParen)5918e5dd7070Spatrick ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET,
5919e5dd7070Spatrick SourceLocation KWLoc,
5920e5dd7070Spatrick Expr *Queried,
5921e5dd7070Spatrick SourceLocation RParen) {
5922e5dd7070Spatrick if (Queried->isTypeDependent()) {
5923e5dd7070Spatrick // Delay type-checking for type-dependent expressions.
5924*12c85518Srobert } else if (Queried->hasPlaceholderType()) {
5925e5dd7070Spatrick ExprResult PE = CheckPlaceholderExpr(Queried);
5926e5dd7070Spatrick if (PE.isInvalid()) return ExprError();
5927e5dd7070Spatrick return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
5928e5dd7070Spatrick }
5929e5dd7070Spatrick
5930e5dd7070Spatrick bool Value = EvaluateExpressionTrait(ET, Queried);
5931e5dd7070Spatrick
5932e5dd7070Spatrick return new (Context)
5933e5dd7070Spatrick ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
5934e5dd7070Spatrick }
5935e5dd7070Spatrick
CheckPointerToMemberOperands(ExprResult & LHS,ExprResult & RHS,ExprValueKind & VK,SourceLocation Loc,bool isIndirect)5936e5dd7070Spatrick QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
5937e5dd7070Spatrick ExprValueKind &VK,
5938e5dd7070Spatrick SourceLocation Loc,
5939e5dd7070Spatrick bool isIndirect) {
5940*12c85518Srobert assert(!LHS.get()->hasPlaceholderType() && !RHS.get()->hasPlaceholderType() &&
5941e5dd7070Spatrick "placeholders should have been weeded out by now");
5942e5dd7070Spatrick
5943e5dd7070Spatrick // The LHS undergoes lvalue conversions if this is ->*, and undergoes the
5944e5dd7070Spatrick // temporary materialization conversion otherwise.
5945e5dd7070Spatrick if (isIndirect)
5946e5dd7070Spatrick LHS = DefaultLvalueConversion(LHS.get());
5947a9ac8606Spatrick else if (LHS.get()->isPRValue())
5948e5dd7070Spatrick LHS = TemporaryMaterializationConversion(LHS.get());
5949e5dd7070Spatrick if (LHS.isInvalid())
5950e5dd7070Spatrick return QualType();
5951e5dd7070Spatrick
5952e5dd7070Spatrick // The RHS always undergoes lvalue conversions.
5953e5dd7070Spatrick RHS = DefaultLvalueConversion(RHS.get());
5954e5dd7070Spatrick if (RHS.isInvalid()) return QualType();
5955e5dd7070Spatrick
5956e5dd7070Spatrick const char *OpSpelling = isIndirect ? "->*" : ".*";
5957e5dd7070Spatrick // C++ 5.5p2
5958e5dd7070Spatrick // The binary operator .* [p3: ->*] binds its second operand, which shall
5959e5dd7070Spatrick // be of type "pointer to member of T" (where T is a completely-defined
5960e5dd7070Spatrick // class type) [...]
5961e5dd7070Spatrick QualType RHSType = RHS.get()->getType();
5962e5dd7070Spatrick const MemberPointerType *MemPtr = RHSType->getAs<MemberPointerType>();
5963e5dd7070Spatrick if (!MemPtr) {
5964e5dd7070Spatrick Diag(Loc, diag::err_bad_memptr_rhs)
5965e5dd7070Spatrick << OpSpelling << RHSType << RHS.get()->getSourceRange();
5966e5dd7070Spatrick return QualType();
5967e5dd7070Spatrick }
5968e5dd7070Spatrick
5969e5dd7070Spatrick QualType Class(MemPtr->getClass(), 0);
5970e5dd7070Spatrick
5971e5dd7070Spatrick // Note: C++ [expr.mptr.oper]p2-3 says that the class type into which the
5972e5dd7070Spatrick // member pointer points must be completely-defined. However, there is no
5973e5dd7070Spatrick // reason for this semantic distinction, and the rule is not enforced by
5974e5dd7070Spatrick // other compilers. Therefore, we do not check this property, as it is
5975e5dd7070Spatrick // likely to be considered a defect.
5976e5dd7070Spatrick
5977e5dd7070Spatrick // C++ 5.5p2
5978e5dd7070Spatrick // [...] to its first operand, which shall be of class T or of a class of
5979e5dd7070Spatrick // which T is an unambiguous and accessible base class. [p3: a pointer to
5980e5dd7070Spatrick // such a class]
5981e5dd7070Spatrick QualType LHSType = LHS.get()->getType();
5982e5dd7070Spatrick if (isIndirect) {
5983e5dd7070Spatrick if (const PointerType *Ptr = LHSType->getAs<PointerType>())
5984e5dd7070Spatrick LHSType = Ptr->getPointeeType();
5985e5dd7070Spatrick else {
5986e5dd7070Spatrick Diag(Loc, diag::err_bad_memptr_lhs)
5987e5dd7070Spatrick << OpSpelling << 1 << LHSType
5988e5dd7070Spatrick << FixItHint::CreateReplacement(SourceRange(Loc), ".*");
5989e5dd7070Spatrick return QualType();
5990e5dd7070Spatrick }
5991e5dd7070Spatrick }
5992e5dd7070Spatrick
5993e5dd7070Spatrick if (!Context.hasSameUnqualifiedType(Class, LHSType)) {
5994e5dd7070Spatrick // If we want to check the hierarchy, we need a complete type.
5995e5dd7070Spatrick if (RequireCompleteType(Loc, LHSType, diag::err_bad_memptr_lhs,
5996e5dd7070Spatrick OpSpelling, (int)isIndirect)) {
5997e5dd7070Spatrick return QualType();
5998e5dd7070Spatrick }
5999e5dd7070Spatrick
6000e5dd7070Spatrick if (!IsDerivedFrom(Loc, LHSType, Class)) {
6001e5dd7070Spatrick Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling
6002e5dd7070Spatrick << (int)isIndirect << LHS.get()->getType();
6003e5dd7070Spatrick return QualType();
6004e5dd7070Spatrick }
6005e5dd7070Spatrick
6006e5dd7070Spatrick CXXCastPath BasePath;
6007e5dd7070Spatrick if (CheckDerivedToBaseConversion(
6008e5dd7070Spatrick LHSType, Class, Loc,
6009e5dd7070Spatrick SourceRange(LHS.get()->getBeginLoc(), RHS.get()->getEndLoc()),
6010e5dd7070Spatrick &BasePath))
6011e5dd7070Spatrick return QualType();
6012e5dd7070Spatrick
6013e5dd7070Spatrick // Cast LHS to type of use.
6014e5dd7070Spatrick QualType UseType = Context.getQualifiedType(Class, LHSType.getQualifiers());
6015e5dd7070Spatrick if (isIndirect)
6016e5dd7070Spatrick UseType = Context.getPointerType(UseType);
6017a9ac8606Spatrick ExprValueKind VK = isIndirect ? VK_PRValue : LHS.get()->getValueKind();
6018e5dd7070Spatrick LHS = ImpCastExprToType(LHS.get(), UseType, CK_DerivedToBase, VK,
6019e5dd7070Spatrick &BasePath);
6020e5dd7070Spatrick }
6021e5dd7070Spatrick
6022e5dd7070Spatrick if (isa<CXXScalarValueInitExpr>(RHS.get()->IgnoreParens())) {
6023e5dd7070Spatrick // Diagnose use of pointer-to-member type which when used as
6024e5dd7070Spatrick // the functional cast in a pointer-to-member expression.
6025e5dd7070Spatrick Diag(Loc, diag::err_pointer_to_member_type) << isIndirect;
6026e5dd7070Spatrick return QualType();
6027e5dd7070Spatrick }
6028e5dd7070Spatrick
6029e5dd7070Spatrick // C++ 5.5p2
6030e5dd7070Spatrick // The result is an object or a function of the type specified by the
6031e5dd7070Spatrick // second operand.
6032e5dd7070Spatrick // The cv qualifiers are the union of those in the pointer and the left side,
6033e5dd7070Spatrick // in accordance with 5.5p5 and 5.2.5.
6034e5dd7070Spatrick QualType Result = MemPtr->getPointeeType();
6035e5dd7070Spatrick Result = Context.getCVRQualifiedType(Result, LHSType.getCVRQualifiers());
6036e5dd7070Spatrick
6037e5dd7070Spatrick // C++0x [expr.mptr.oper]p6:
6038e5dd7070Spatrick // In a .* expression whose object expression is an rvalue, the program is
6039e5dd7070Spatrick // ill-formed if the second operand is a pointer to member function with
6040e5dd7070Spatrick // ref-qualifier &. In a ->* expression or in a .* expression whose object
6041e5dd7070Spatrick // expression is an lvalue, the program is ill-formed if the second operand
6042e5dd7070Spatrick // is a pointer to member function with ref-qualifier &&.
6043e5dd7070Spatrick if (const FunctionProtoType *Proto = Result->getAs<FunctionProtoType>()) {
6044e5dd7070Spatrick switch (Proto->getRefQualifier()) {
6045e5dd7070Spatrick case RQ_None:
6046e5dd7070Spatrick // Do nothing
6047e5dd7070Spatrick break;
6048e5dd7070Spatrick
6049e5dd7070Spatrick case RQ_LValue:
6050e5dd7070Spatrick if (!isIndirect && !LHS.get()->Classify(Context).isLValue()) {
6051e5dd7070Spatrick // C++2a allows functions with ref-qualifier & if their cv-qualifier-seq
6052e5dd7070Spatrick // is (exactly) 'const'.
6053e5dd7070Spatrick if (Proto->isConst() && !Proto->isVolatile())
6054ec727ea7Spatrick Diag(Loc, getLangOpts().CPlusPlus20
6055e5dd7070Spatrick ? diag::warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue
6056e5dd7070Spatrick : diag::ext_pointer_to_const_ref_member_on_rvalue);
6057e5dd7070Spatrick else
6058e5dd7070Spatrick Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
6059e5dd7070Spatrick << RHSType << 1 << LHS.get()->getSourceRange();
6060e5dd7070Spatrick }
6061e5dd7070Spatrick break;
6062e5dd7070Spatrick
6063e5dd7070Spatrick case RQ_RValue:
6064e5dd7070Spatrick if (isIndirect || !LHS.get()->Classify(Context).isRValue())
6065e5dd7070Spatrick Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
6066e5dd7070Spatrick << RHSType << 0 << LHS.get()->getSourceRange();
6067e5dd7070Spatrick break;
6068e5dd7070Spatrick }
6069e5dd7070Spatrick }
6070e5dd7070Spatrick
6071e5dd7070Spatrick // C++ [expr.mptr.oper]p6:
6072e5dd7070Spatrick // The result of a .* expression whose second operand is a pointer
6073e5dd7070Spatrick // to a data member is of the same value category as its
6074e5dd7070Spatrick // first operand. The result of a .* expression whose second
6075e5dd7070Spatrick // operand is a pointer to a member function is a prvalue. The
6076e5dd7070Spatrick // result of an ->* expression is an lvalue if its second operand
6077e5dd7070Spatrick // is a pointer to data member and a prvalue otherwise.
6078e5dd7070Spatrick if (Result->isFunctionType()) {
6079a9ac8606Spatrick VK = VK_PRValue;
6080e5dd7070Spatrick return Context.BoundMemberTy;
6081e5dd7070Spatrick } else if (isIndirect) {
6082e5dd7070Spatrick VK = VK_LValue;
6083e5dd7070Spatrick } else {
6084e5dd7070Spatrick VK = LHS.get()->getValueKind();
6085e5dd7070Spatrick }
6086e5dd7070Spatrick
6087e5dd7070Spatrick return Result;
6088e5dd7070Spatrick }
6089e5dd7070Spatrick
6090e5dd7070Spatrick /// Try to convert a type to another according to C++11 5.16p3.
6091e5dd7070Spatrick ///
6092e5dd7070Spatrick /// This is part of the parameter validation for the ? operator. If either
6093e5dd7070Spatrick /// value operand is a class type, the two operands are attempted to be
6094e5dd7070Spatrick /// converted to each other. This function does the conversion in one direction.
6095e5dd7070Spatrick /// It returns true if the program is ill-formed and has already been diagnosed
6096e5dd7070Spatrick /// as such.
TryClassUnification(Sema & Self,Expr * From,Expr * To,SourceLocation QuestionLoc,bool & HaveConversion,QualType & ToType)6097e5dd7070Spatrick static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
6098e5dd7070Spatrick SourceLocation QuestionLoc,
6099e5dd7070Spatrick bool &HaveConversion,
6100e5dd7070Spatrick QualType &ToType) {
6101e5dd7070Spatrick HaveConversion = false;
6102e5dd7070Spatrick ToType = To->getType();
6103e5dd7070Spatrick
6104e5dd7070Spatrick InitializationKind Kind =
6105e5dd7070Spatrick InitializationKind::CreateCopy(To->getBeginLoc(), SourceLocation());
6106e5dd7070Spatrick // C++11 5.16p3
6107e5dd7070Spatrick // The process for determining whether an operand expression E1 of type T1
6108e5dd7070Spatrick // can be converted to match an operand expression E2 of type T2 is defined
6109e5dd7070Spatrick // as follows:
6110e5dd7070Spatrick // -- If E2 is an lvalue: E1 can be converted to match E2 if E1 can be
6111e5dd7070Spatrick // implicitly converted to type "lvalue reference to T2", subject to the
6112e5dd7070Spatrick // constraint that in the conversion the reference must bind directly to
6113e5dd7070Spatrick // an lvalue.
6114e5dd7070Spatrick // -- If E2 is an xvalue: E1 can be converted to match E2 if E1 can be
6115e5dd7070Spatrick // implicitly converted to the type "rvalue reference to R2", subject to
6116e5dd7070Spatrick // the constraint that the reference must bind directly.
6117*12c85518Srobert if (To->isGLValue()) {
6118*12c85518Srobert QualType T = Self.Context.getReferenceQualifiedType(To);
6119e5dd7070Spatrick InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
6120e5dd7070Spatrick
6121e5dd7070Spatrick InitializationSequence InitSeq(Self, Entity, Kind, From);
6122e5dd7070Spatrick if (InitSeq.isDirectReferenceBinding()) {
6123e5dd7070Spatrick ToType = T;
6124e5dd7070Spatrick HaveConversion = true;
6125e5dd7070Spatrick return false;
6126e5dd7070Spatrick }
6127e5dd7070Spatrick
6128e5dd7070Spatrick if (InitSeq.isAmbiguous())
6129e5dd7070Spatrick return InitSeq.Diagnose(Self, Entity, Kind, From);
6130e5dd7070Spatrick }
6131e5dd7070Spatrick
6132e5dd7070Spatrick // -- If E2 is an rvalue, or if the conversion above cannot be done:
6133e5dd7070Spatrick // -- if E1 and E2 have class type, and the underlying class types are
6134e5dd7070Spatrick // the same or one is a base class of the other:
6135e5dd7070Spatrick QualType FTy = From->getType();
6136e5dd7070Spatrick QualType TTy = To->getType();
6137e5dd7070Spatrick const RecordType *FRec = FTy->getAs<RecordType>();
6138e5dd7070Spatrick const RecordType *TRec = TTy->getAs<RecordType>();
6139e5dd7070Spatrick bool FDerivedFromT = FRec && TRec && FRec != TRec &&
6140e5dd7070Spatrick Self.IsDerivedFrom(QuestionLoc, FTy, TTy);
6141e5dd7070Spatrick if (FRec && TRec && (FRec == TRec || FDerivedFromT ||
6142e5dd7070Spatrick Self.IsDerivedFrom(QuestionLoc, TTy, FTy))) {
6143e5dd7070Spatrick // E1 can be converted to match E2 if the class of T2 is the
6144e5dd7070Spatrick // same type as, or a base class of, the class of T1, and
6145e5dd7070Spatrick // [cv2 > cv1].
6146e5dd7070Spatrick if (FRec == TRec || FDerivedFromT) {
6147e5dd7070Spatrick if (TTy.isAtLeastAsQualifiedAs(FTy)) {
6148e5dd7070Spatrick InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy);
6149e5dd7070Spatrick InitializationSequence InitSeq(Self, Entity, Kind, From);
6150e5dd7070Spatrick if (InitSeq) {
6151e5dd7070Spatrick HaveConversion = true;
6152e5dd7070Spatrick return false;
6153e5dd7070Spatrick }
6154e5dd7070Spatrick
6155e5dd7070Spatrick if (InitSeq.isAmbiguous())
6156e5dd7070Spatrick return InitSeq.Diagnose(Self, Entity, Kind, From);
6157e5dd7070Spatrick }
6158e5dd7070Spatrick }
6159e5dd7070Spatrick
6160e5dd7070Spatrick return false;
6161e5dd7070Spatrick }
6162e5dd7070Spatrick
6163e5dd7070Spatrick // -- Otherwise: E1 can be converted to match E2 if E1 can be
6164e5dd7070Spatrick // implicitly converted to the type that expression E2 would have
6165e5dd7070Spatrick // if E2 were converted to an rvalue (or the type it has, if E2 is
6166e5dd7070Spatrick // an rvalue).
6167e5dd7070Spatrick //
6168e5dd7070Spatrick // This actually refers very narrowly to the lvalue-to-rvalue conversion, not
6169e5dd7070Spatrick // to the array-to-pointer or function-to-pointer conversions.
6170e5dd7070Spatrick TTy = TTy.getNonLValueExprType(Self.Context);
6171e5dd7070Spatrick
6172e5dd7070Spatrick InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy);
6173e5dd7070Spatrick InitializationSequence InitSeq(Self, Entity, Kind, From);
6174e5dd7070Spatrick HaveConversion = !InitSeq.Failed();
6175e5dd7070Spatrick ToType = TTy;
6176e5dd7070Spatrick if (InitSeq.isAmbiguous())
6177e5dd7070Spatrick return InitSeq.Diagnose(Self, Entity, Kind, From);
6178e5dd7070Spatrick
6179e5dd7070Spatrick return false;
6180e5dd7070Spatrick }
6181e5dd7070Spatrick
6182e5dd7070Spatrick /// Try to find a common type for two according to C++0x 5.16p5.
6183e5dd7070Spatrick ///
6184e5dd7070Spatrick /// This is part of the parameter validation for the ? operator. If either
6185e5dd7070Spatrick /// value operand is a class type, overload resolution is used to find a
6186e5dd7070Spatrick /// conversion to a common type.
FindConditionalOverload(Sema & Self,ExprResult & LHS,ExprResult & RHS,SourceLocation QuestionLoc)6187e5dd7070Spatrick static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS,
6188e5dd7070Spatrick SourceLocation QuestionLoc) {
6189e5dd7070Spatrick Expr *Args[2] = { LHS.get(), RHS.get() };
6190e5dd7070Spatrick OverloadCandidateSet CandidateSet(QuestionLoc,
6191e5dd7070Spatrick OverloadCandidateSet::CSK_Operator);
6192e5dd7070Spatrick Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args,
6193e5dd7070Spatrick CandidateSet);
6194e5dd7070Spatrick
6195e5dd7070Spatrick OverloadCandidateSet::iterator Best;
6196e5dd7070Spatrick switch (CandidateSet.BestViableFunction(Self, QuestionLoc, Best)) {
6197e5dd7070Spatrick case OR_Success: {
6198e5dd7070Spatrick // We found a match. Perform the conversions on the arguments and move on.
6199e5dd7070Spatrick ExprResult LHSRes = Self.PerformImplicitConversion(
6200e5dd7070Spatrick LHS.get(), Best->BuiltinParamTypes[0], Best->Conversions[0],
6201e5dd7070Spatrick Sema::AA_Converting);
6202e5dd7070Spatrick if (LHSRes.isInvalid())
6203e5dd7070Spatrick break;
6204e5dd7070Spatrick LHS = LHSRes;
6205e5dd7070Spatrick
6206e5dd7070Spatrick ExprResult RHSRes = Self.PerformImplicitConversion(
6207e5dd7070Spatrick RHS.get(), Best->BuiltinParamTypes[1], Best->Conversions[1],
6208e5dd7070Spatrick Sema::AA_Converting);
6209e5dd7070Spatrick if (RHSRes.isInvalid())
6210e5dd7070Spatrick break;
6211e5dd7070Spatrick RHS = RHSRes;
6212e5dd7070Spatrick if (Best->Function)
6213e5dd7070Spatrick Self.MarkFunctionReferenced(QuestionLoc, Best->Function);
6214e5dd7070Spatrick return false;
6215e5dd7070Spatrick }
6216e5dd7070Spatrick
6217e5dd7070Spatrick case OR_No_Viable_Function:
6218e5dd7070Spatrick
6219e5dd7070Spatrick // Emit a better diagnostic if one of the expressions is a null pointer
6220e5dd7070Spatrick // constant and the other is a pointer type. In this case, the user most
6221e5dd7070Spatrick // likely forgot to take the address of the other expression.
6222e5dd7070Spatrick if (Self.DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc))
6223e5dd7070Spatrick return true;
6224e5dd7070Spatrick
6225e5dd7070Spatrick Self.Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
6226e5dd7070Spatrick << LHS.get()->getType() << RHS.get()->getType()
6227e5dd7070Spatrick << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
6228e5dd7070Spatrick return true;
6229e5dd7070Spatrick
6230e5dd7070Spatrick case OR_Ambiguous:
6231e5dd7070Spatrick Self.Diag(QuestionLoc, diag::err_conditional_ambiguous_ovl)
6232e5dd7070Spatrick << LHS.get()->getType() << RHS.get()->getType()
6233e5dd7070Spatrick << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
6234e5dd7070Spatrick // FIXME: Print the possible common types by printing the return types of
6235e5dd7070Spatrick // the viable candidates.
6236e5dd7070Spatrick break;
6237e5dd7070Spatrick
6238e5dd7070Spatrick case OR_Deleted:
6239e5dd7070Spatrick llvm_unreachable("Conditional operator has only built-in overloads");
6240e5dd7070Spatrick }
6241e5dd7070Spatrick return true;
6242e5dd7070Spatrick }
6243e5dd7070Spatrick
6244e5dd7070Spatrick /// Perform an "extended" implicit conversion as returned by
6245e5dd7070Spatrick /// TryClassUnification.
ConvertForConditional(Sema & Self,ExprResult & E,QualType T)6246e5dd7070Spatrick static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) {
6247e5dd7070Spatrick InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
6248e5dd7070Spatrick InitializationKind Kind =
6249e5dd7070Spatrick InitializationKind::CreateCopy(E.get()->getBeginLoc(), SourceLocation());
6250e5dd7070Spatrick Expr *Arg = E.get();
6251e5dd7070Spatrick InitializationSequence InitSeq(Self, Entity, Kind, Arg);
6252e5dd7070Spatrick ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg);
6253e5dd7070Spatrick if (Result.isInvalid())
6254e5dd7070Spatrick return true;
6255e5dd7070Spatrick
6256e5dd7070Spatrick E = Result;
6257e5dd7070Spatrick return false;
6258e5dd7070Spatrick }
6259e5dd7070Spatrick
6260e5dd7070Spatrick // Check the condition operand of ?: to see if it is valid for the GCC
6261e5dd7070Spatrick // extension.
isValidVectorForConditionalCondition(ASTContext & Ctx,QualType CondTy)6262e5dd7070Spatrick static bool isValidVectorForConditionalCondition(ASTContext &Ctx,
6263e5dd7070Spatrick QualType CondTy) {
6264a9ac8606Spatrick if (!CondTy->isVectorType() && !CondTy->isExtVectorType())
6265e5dd7070Spatrick return false;
6266e5dd7070Spatrick const QualType EltTy =
6267e5dd7070Spatrick cast<VectorType>(CondTy.getCanonicalType())->getElementType();
6268*12c85518Srobert assert(!EltTy->isEnumeralType() && "Vectors cant be enum types");
6269*12c85518Srobert return EltTy->isIntegralType(Ctx);
6270*12c85518Srobert }
6271*12c85518Srobert
isValidSizelessVectorForConditionalCondition(ASTContext & Ctx,QualType CondTy)6272*12c85518Srobert static bool isValidSizelessVectorForConditionalCondition(ASTContext &Ctx,
6273*12c85518Srobert QualType CondTy) {
6274*12c85518Srobert if (!CondTy->isVLSTBuiltinType())
6275*12c85518Srobert return false;
6276*12c85518Srobert const QualType EltTy =
6277*12c85518Srobert cast<BuiltinType>(CondTy.getCanonicalType())->getSveEltType(Ctx);
6278*12c85518Srobert assert(!EltTy->isEnumeralType() && "Vectors cant be enum types");
6279e5dd7070Spatrick return EltTy->isIntegralType(Ctx);
6280e5dd7070Spatrick }
6281e5dd7070Spatrick
CheckVectorConditionalTypes(ExprResult & Cond,ExprResult & LHS,ExprResult & RHS,SourceLocation QuestionLoc)6282a9ac8606Spatrick QualType Sema::CheckVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
6283e5dd7070Spatrick ExprResult &RHS,
6284e5dd7070Spatrick SourceLocation QuestionLoc) {
6285e5dd7070Spatrick LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
6286e5dd7070Spatrick RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
6287e5dd7070Spatrick
6288e5dd7070Spatrick QualType CondType = Cond.get()->getType();
6289ec727ea7Spatrick const auto *CondVT = CondType->castAs<VectorType>();
6290e5dd7070Spatrick QualType CondElementTy = CondVT->getElementType();
6291e5dd7070Spatrick unsigned CondElementCount = CondVT->getNumElements();
6292e5dd7070Spatrick QualType LHSType = LHS.get()->getType();
6293e5dd7070Spatrick const auto *LHSVT = LHSType->getAs<VectorType>();
6294e5dd7070Spatrick QualType RHSType = RHS.get()->getType();
6295e5dd7070Spatrick const auto *RHSVT = RHSType->getAs<VectorType>();
6296e5dd7070Spatrick
6297e5dd7070Spatrick QualType ResultType;
6298e5dd7070Spatrick
6299e5dd7070Spatrick
6300e5dd7070Spatrick if (LHSVT && RHSVT) {
6301a9ac8606Spatrick if (isa<ExtVectorType>(CondVT) != isa<ExtVectorType>(LHSVT)) {
6302a9ac8606Spatrick Diag(QuestionLoc, diag::err_conditional_vector_cond_result_mismatch)
6303a9ac8606Spatrick << /*isExtVector*/ isa<ExtVectorType>(CondVT);
6304a9ac8606Spatrick return {};
6305a9ac8606Spatrick }
6306a9ac8606Spatrick
6307e5dd7070Spatrick // If both are vector types, they must be the same type.
6308e5dd7070Spatrick if (!Context.hasSameType(LHSType, RHSType)) {
6309a9ac8606Spatrick Diag(QuestionLoc, diag::err_conditional_vector_mismatched)
6310e5dd7070Spatrick << LHSType << RHSType;
6311e5dd7070Spatrick return {};
6312e5dd7070Spatrick }
6313*12c85518Srobert ResultType = Context.getCommonSugaredType(LHSType, RHSType);
6314e5dd7070Spatrick } else if (LHSVT || RHSVT) {
6315e5dd7070Spatrick ResultType = CheckVectorOperands(
6316e5dd7070Spatrick LHS, RHS, QuestionLoc, /*isCompAssign*/ false, /*AllowBothBool*/ true,
6317*12c85518Srobert /*AllowBoolConversions*/ false,
6318*12c85518Srobert /*AllowBoolOperation*/ true,
6319*12c85518Srobert /*ReportInvalid*/ true);
6320e5dd7070Spatrick if (ResultType.isNull())
6321e5dd7070Spatrick return {};
6322e5dd7070Spatrick } else {
6323e5dd7070Spatrick // Both are scalar.
6324*12c85518Srobert LHSType = LHSType.getUnqualifiedType();
6325*12c85518Srobert RHSType = RHSType.getUnqualifiedType();
6326*12c85518Srobert QualType ResultElementTy =
6327*12c85518Srobert Context.hasSameType(LHSType, RHSType)
6328*12c85518Srobert ? Context.getCommonSugaredType(LHSType, RHSType)
6329*12c85518Srobert : UsualArithmeticConversions(LHS, RHS, QuestionLoc,
6330*12c85518Srobert ACK_Conditional);
6331e5dd7070Spatrick
6332e5dd7070Spatrick if (ResultElementTy->isEnumeralType()) {
6333e5dd7070Spatrick Diag(QuestionLoc, diag::err_conditional_vector_operand_type)
6334a9ac8606Spatrick << ResultElementTy;
6335e5dd7070Spatrick return {};
6336e5dd7070Spatrick }
6337a9ac8606Spatrick if (CondType->isExtVectorType())
6338a9ac8606Spatrick ResultType =
6339a9ac8606Spatrick Context.getExtVectorType(ResultElementTy, CondVT->getNumElements());
6340a9ac8606Spatrick else
6341e5dd7070Spatrick ResultType = Context.getVectorType(
6342a9ac8606Spatrick ResultElementTy, CondVT->getNumElements(), VectorType::GenericVector);
6343e5dd7070Spatrick
6344e5dd7070Spatrick LHS = ImpCastExprToType(LHS.get(), ResultType, CK_VectorSplat);
6345e5dd7070Spatrick RHS = ImpCastExprToType(RHS.get(), ResultType, CK_VectorSplat);
6346e5dd7070Spatrick }
6347e5dd7070Spatrick
6348e5dd7070Spatrick assert(!ResultType.isNull() && ResultType->isVectorType() &&
6349a9ac8606Spatrick (!CondType->isExtVectorType() || ResultType->isExtVectorType()) &&
6350e5dd7070Spatrick "Result should have been a vector type");
6351ec727ea7Spatrick auto *ResultVectorTy = ResultType->castAs<VectorType>();
6352ec727ea7Spatrick QualType ResultElementTy = ResultVectorTy->getElementType();
6353ec727ea7Spatrick unsigned ResultElementCount = ResultVectorTy->getNumElements();
6354e5dd7070Spatrick
6355e5dd7070Spatrick if (ResultElementCount != CondElementCount) {
6356e5dd7070Spatrick Diag(QuestionLoc, diag::err_conditional_vector_size) << CondType
6357e5dd7070Spatrick << ResultType;
6358e5dd7070Spatrick return {};
6359e5dd7070Spatrick }
6360e5dd7070Spatrick
6361e5dd7070Spatrick if (Context.getTypeSize(ResultElementTy) !=
6362e5dd7070Spatrick Context.getTypeSize(CondElementTy)) {
6363e5dd7070Spatrick Diag(QuestionLoc, diag::err_conditional_vector_element_size) << CondType
6364e5dd7070Spatrick << ResultType;
6365e5dd7070Spatrick return {};
6366e5dd7070Spatrick }
6367e5dd7070Spatrick
6368e5dd7070Spatrick return ResultType;
6369e5dd7070Spatrick }
6370e5dd7070Spatrick
CheckSizelessVectorConditionalTypes(ExprResult & Cond,ExprResult & LHS,ExprResult & RHS,SourceLocation QuestionLoc)6371*12c85518Srobert QualType Sema::CheckSizelessVectorConditionalTypes(ExprResult &Cond,
6372*12c85518Srobert ExprResult &LHS,
6373*12c85518Srobert ExprResult &RHS,
6374*12c85518Srobert SourceLocation QuestionLoc) {
6375*12c85518Srobert LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
6376*12c85518Srobert RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
6377*12c85518Srobert
6378*12c85518Srobert QualType CondType = Cond.get()->getType();
6379*12c85518Srobert const auto *CondBT = CondType->castAs<BuiltinType>();
6380*12c85518Srobert QualType CondElementTy = CondBT->getSveEltType(Context);
6381*12c85518Srobert llvm::ElementCount CondElementCount =
6382*12c85518Srobert Context.getBuiltinVectorTypeInfo(CondBT).EC;
6383*12c85518Srobert
6384*12c85518Srobert QualType LHSType = LHS.get()->getType();
6385*12c85518Srobert const auto *LHSBT =
6386*12c85518Srobert LHSType->isVLSTBuiltinType() ? LHSType->getAs<BuiltinType>() : nullptr;
6387*12c85518Srobert QualType RHSType = RHS.get()->getType();
6388*12c85518Srobert const auto *RHSBT =
6389*12c85518Srobert RHSType->isVLSTBuiltinType() ? RHSType->getAs<BuiltinType>() : nullptr;
6390*12c85518Srobert
6391*12c85518Srobert QualType ResultType;
6392*12c85518Srobert
6393*12c85518Srobert if (LHSBT && RHSBT) {
6394*12c85518Srobert // If both are sizeless vector types, they must be the same type.
6395*12c85518Srobert if (!Context.hasSameType(LHSType, RHSType)) {
6396*12c85518Srobert Diag(QuestionLoc, diag::err_conditional_vector_mismatched)
6397*12c85518Srobert << LHSType << RHSType;
6398*12c85518Srobert return QualType();
6399*12c85518Srobert }
6400*12c85518Srobert ResultType = LHSType;
6401*12c85518Srobert } else if (LHSBT || RHSBT) {
6402*12c85518Srobert ResultType = CheckSizelessVectorOperands(
6403*12c85518Srobert LHS, RHS, QuestionLoc, /*IsCompAssign*/ false, ACK_Conditional);
6404*12c85518Srobert if (ResultType.isNull())
6405*12c85518Srobert return QualType();
6406*12c85518Srobert } else {
6407*12c85518Srobert // Both are scalar so splat
6408*12c85518Srobert QualType ResultElementTy;
6409*12c85518Srobert LHSType = LHSType.getCanonicalType().getUnqualifiedType();
6410*12c85518Srobert RHSType = RHSType.getCanonicalType().getUnqualifiedType();
6411*12c85518Srobert
6412*12c85518Srobert if (Context.hasSameType(LHSType, RHSType))
6413*12c85518Srobert ResultElementTy = LHSType;
6414*12c85518Srobert else
6415*12c85518Srobert ResultElementTy =
6416*12c85518Srobert UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional);
6417*12c85518Srobert
6418*12c85518Srobert if (ResultElementTy->isEnumeralType()) {
6419*12c85518Srobert Diag(QuestionLoc, diag::err_conditional_vector_operand_type)
6420*12c85518Srobert << ResultElementTy;
6421*12c85518Srobert return QualType();
6422*12c85518Srobert }
6423*12c85518Srobert
6424*12c85518Srobert ResultType = Context.getScalableVectorType(
6425*12c85518Srobert ResultElementTy, CondElementCount.getKnownMinValue());
6426*12c85518Srobert
6427*12c85518Srobert LHS = ImpCastExprToType(LHS.get(), ResultType, CK_VectorSplat);
6428*12c85518Srobert RHS = ImpCastExprToType(RHS.get(), ResultType, CK_VectorSplat);
6429*12c85518Srobert }
6430*12c85518Srobert
6431*12c85518Srobert assert(!ResultType.isNull() && ResultType->isVLSTBuiltinType() &&
6432*12c85518Srobert "Result should have been a vector type");
6433*12c85518Srobert auto *ResultBuiltinTy = ResultType->castAs<BuiltinType>();
6434*12c85518Srobert QualType ResultElementTy = ResultBuiltinTy->getSveEltType(Context);
6435*12c85518Srobert llvm::ElementCount ResultElementCount =
6436*12c85518Srobert Context.getBuiltinVectorTypeInfo(ResultBuiltinTy).EC;
6437*12c85518Srobert
6438*12c85518Srobert if (ResultElementCount != CondElementCount) {
6439*12c85518Srobert Diag(QuestionLoc, diag::err_conditional_vector_size)
6440*12c85518Srobert << CondType << ResultType;
6441*12c85518Srobert return QualType();
6442*12c85518Srobert }
6443*12c85518Srobert
6444*12c85518Srobert if (Context.getTypeSize(ResultElementTy) !=
6445*12c85518Srobert Context.getTypeSize(CondElementTy)) {
6446*12c85518Srobert Diag(QuestionLoc, diag::err_conditional_vector_element_size)
6447*12c85518Srobert << CondType << ResultType;
6448*12c85518Srobert return QualType();
6449*12c85518Srobert }
6450*12c85518Srobert
6451*12c85518Srobert return ResultType;
6452*12c85518Srobert }
6453*12c85518Srobert
6454e5dd7070Spatrick /// Check the operands of ?: under C++ semantics.
6455e5dd7070Spatrick ///
6456e5dd7070Spatrick /// See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y
6457e5dd7070Spatrick /// extension. In this case, LHS == Cond. (But they're not aliases.)
6458e5dd7070Spatrick ///
6459a9ac8606Spatrick /// This function also implements GCC's vector extension and the
6460a9ac8606Spatrick /// OpenCL/ext_vector_type extension for conditionals. The vector extensions
6461a9ac8606Spatrick /// permit the use of a?b:c where the type of a is that of a integer vector with
6462a9ac8606Spatrick /// the same number of elements and size as the vectors of b and c. If one of
6463a9ac8606Spatrick /// either b or c is a scalar it is implicitly converted to match the type of
6464a9ac8606Spatrick /// the vector. Otherwise the expression is ill-formed. If both b and c are
6465a9ac8606Spatrick /// scalars, then b and c are checked and converted to the type of a if
6466a9ac8606Spatrick /// possible.
6467a9ac8606Spatrick ///
6468a9ac8606Spatrick /// The expressions are evaluated differently for GCC's and OpenCL's extensions.
6469a9ac8606Spatrick /// For the GCC extension, the ?: operator is evaluated as
6470e5dd7070Spatrick /// (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]).
6471a9ac8606Spatrick /// For the OpenCL extensions, the ?: operator is evaluated as
6472a9ac8606Spatrick /// (most-significant-bit-set(a[0]) ? b[0] : c[0], .. ,
6473a9ac8606Spatrick /// most-significant-bit-set(a[n]) ? b[n] : c[n]).
CXXCheckConditionalOperands(ExprResult & Cond,ExprResult & LHS,ExprResult & RHS,ExprValueKind & VK,ExprObjectKind & OK,SourceLocation QuestionLoc)6474e5dd7070Spatrick QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
6475e5dd7070Spatrick ExprResult &RHS, ExprValueKind &VK,
6476e5dd7070Spatrick ExprObjectKind &OK,
6477e5dd7070Spatrick SourceLocation QuestionLoc) {
6478e5dd7070Spatrick // FIXME: Handle C99's complex types, block pointers and Obj-C++ interface
6479e5dd7070Spatrick // pointers.
6480e5dd7070Spatrick
6481e5dd7070Spatrick // Assume r-value.
6482a9ac8606Spatrick VK = VK_PRValue;
6483e5dd7070Spatrick OK = OK_Ordinary;
6484e5dd7070Spatrick bool IsVectorConditional =
6485e5dd7070Spatrick isValidVectorForConditionalCondition(Context, Cond.get()->getType());
6486e5dd7070Spatrick
6487*12c85518Srobert bool IsSizelessVectorConditional =
6488*12c85518Srobert isValidSizelessVectorForConditionalCondition(Context,
6489*12c85518Srobert Cond.get()->getType());
6490*12c85518Srobert
6491e5dd7070Spatrick // C++11 [expr.cond]p1
6492e5dd7070Spatrick // The first expression is contextually converted to bool.
6493e5dd7070Spatrick if (!Cond.get()->isTypeDependent()) {
6494*12c85518Srobert ExprResult CondRes = IsVectorConditional || IsSizelessVectorConditional
6495e5dd7070Spatrick ? DefaultFunctionArrayLvalueConversion(Cond.get())
6496e5dd7070Spatrick : CheckCXXBooleanCondition(Cond.get());
6497e5dd7070Spatrick if (CondRes.isInvalid())
6498e5dd7070Spatrick return QualType();
6499e5dd7070Spatrick Cond = CondRes;
6500e5dd7070Spatrick } else {
6501e5dd7070Spatrick // To implement C++, the first expression typically doesn't alter the result
6502e5dd7070Spatrick // type of the conditional, however the GCC compatible vector extension
6503e5dd7070Spatrick // changes the result type to be that of the conditional. Since we cannot
6504e5dd7070Spatrick // know if this is a vector extension here, delay the conversion of the
6505e5dd7070Spatrick // LHS/RHS below until later.
6506e5dd7070Spatrick return Context.DependentTy;
6507e5dd7070Spatrick }
6508e5dd7070Spatrick
6509e5dd7070Spatrick
6510e5dd7070Spatrick // Either of the arguments dependent?
6511e5dd7070Spatrick if (LHS.get()->isTypeDependent() || RHS.get()->isTypeDependent())
6512e5dd7070Spatrick return Context.DependentTy;
6513e5dd7070Spatrick
6514e5dd7070Spatrick // C++11 [expr.cond]p2
6515e5dd7070Spatrick // If either the second or the third operand has type (cv) void, ...
6516e5dd7070Spatrick QualType LTy = LHS.get()->getType();
6517e5dd7070Spatrick QualType RTy = RHS.get()->getType();
6518e5dd7070Spatrick bool LVoid = LTy->isVoidType();
6519e5dd7070Spatrick bool RVoid = RTy->isVoidType();
6520e5dd7070Spatrick if (LVoid || RVoid) {
6521e5dd7070Spatrick // ... one of the following shall hold:
6522e5dd7070Spatrick // -- The second or the third operand (but not both) is a (possibly
6523e5dd7070Spatrick // parenthesized) throw-expression; the result is of the type
6524e5dd7070Spatrick // and value category of the other.
6525e5dd7070Spatrick bool LThrow = isa<CXXThrowExpr>(LHS.get()->IgnoreParenImpCasts());
6526e5dd7070Spatrick bool RThrow = isa<CXXThrowExpr>(RHS.get()->IgnoreParenImpCasts());
6527e5dd7070Spatrick
6528e5dd7070Spatrick // Void expressions aren't legal in the vector-conditional expressions.
6529e5dd7070Spatrick if (IsVectorConditional) {
6530e5dd7070Spatrick SourceRange DiagLoc =
6531e5dd7070Spatrick LVoid ? LHS.get()->getSourceRange() : RHS.get()->getSourceRange();
6532e5dd7070Spatrick bool IsThrow = LVoid ? LThrow : RThrow;
6533e5dd7070Spatrick Diag(DiagLoc.getBegin(), diag::err_conditional_vector_has_void)
6534e5dd7070Spatrick << DiagLoc << IsThrow;
6535e5dd7070Spatrick return QualType();
6536e5dd7070Spatrick }
6537e5dd7070Spatrick
6538e5dd7070Spatrick if (LThrow != RThrow) {
6539e5dd7070Spatrick Expr *NonThrow = LThrow ? RHS.get() : LHS.get();
6540e5dd7070Spatrick VK = NonThrow->getValueKind();
6541e5dd7070Spatrick // DR (no number yet): the result is a bit-field if the
6542e5dd7070Spatrick // non-throw-expression operand is a bit-field.
6543e5dd7070Spatrick OK = NonThrow->getObjectKind();
6544e5dd7070Spatrick return NonThrow->getType();
6545e5dd7070Spatrick }
6546e5dd7070Spatrick
6547e5dd7070Spatrick // -- Both the second and third operands have type void; the result is of
6548e5dd7070Spatrick // type void and is a prvalue.
6549e5dd7070Spatrick if (LVoid && RVoid)
6550*12c85518Srobert return Context.getCommonSugaredType(LTy, RTy);
6551e5dd7070Spatrick
6552e5dd7070Spatrick // Neither holds, error.
6553e5dd7070Spatrick Diag(QuestionLoc, diag::err_conditional_void_nonvoid)
6554e5dd7070Spatrick << (LVoid ? RTy : LTy) << (LVoid ? 0 : 1)
6555e5dd7070Spatrick << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
6556e5dd7070Spatrick return QualType();
6557e5dd7070Spatrick }
6558e5dd7070Spatrick
6559e5dd7070Spatrick // Neither is void.
6560e5dd7070Spatrick if (IsVectorConditional)
6561a9ac8606Spatrick return CheckVectorConditionalTypes(Cond, LHS, RHS, QuestionLoc);
6562e5dd7070Spatrick
6563*12c85518Srobert if (IsSizelessVectorConditional)
6564*12c85518Srobert return CheckSizelessVectorConditionalTypes(Cond, LHS, RHS, QuestionLoc);
6565*12c85518Srobert
6566e5dd7070Spatrick // C++11 [expr.cond]p3
6567e5dd7070Spatrick // Otherwise, if the second and third operand have different types, and
6568e5dd7070Spatrick // either has (cv) class type [...] an attempt is made to convert each of
6569e5dd7070Spatrick // those operands to the type of the other.
6570e5dd7070Spatrick if (!Context.hasSameType(LTy, RTy) &&
6571e5dd7070Spatrick (LTy->isRecordType() || RTy->isRecordType())) {
6572e5dd7070Spatrick // These return true if a single direction is already ambiguous.
6573e5dd7070Spatrick QualType L2RType, R2LType;
6574e5dd7070Spatrick bool HaveL2R, HaveR2L;
6575e5dd7070Spatrick if (TryClassUnification(*this, LHS.get(), RHS.get(), QuestionLoc, HaveL2R, L2RType))
6576e5dd7070Spatrick return QualType();
6577e5dd7070Spatrick if (TryClassUnification(*this, RHS.get(), LHS.get(), QuestionLoc, HaveR2L, R2LType))
6578e5dd7070Spatrick return QualType();
6579e5dd7070Spatrick
6580e5dd7070Spatrick // If both can be converted, [...] the program is ill-formed.
6581e5dd7070Spatrick if (HaveL2R && HaveR2L) {
6582e5dd7070Spatrick Diag(QuestionLoc, diag::err_conditional_ambiguous)
6583e5dd7070Spatrick << LTy << RTy << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
6584e5dd7070Spatrick return QualType();
6585e5dd7070Spatrick }
6586e5dd7070Spatrick
6587e5dd7070Spatrick // If exactly one conversion is possible, that conversion is applied to
6588e5dd7070Spatrick // the chosen operand and the converted operands are used in place of the
6589e5dd7070Spatrick // original operands for the remainder of this section.
6590e5dd7070Spatrick if (HaveL2R) {
6591e5dd7070Spatrick if (ConvertForConditional(*this, LHS, L2RType) || LHS.isInvalid())
6592e5dd7070Spatrick return QualType();
6593e5dd7070Spatrick LTy = LHS.get()->getType();
6594e5dd7070Spatrick } else if (HaveR2L) {
6595e5dd7070Spatrick if (ConvertForConditional(*this, RHS, R2LType) || RHS.isInvalid())
6596e5dd7070Spatrick return QualType();
6597e5dd7070Spatrick RTy = RHS.get()->getType();
6598e5dd7070Spatrick }
6599e5dd7070Spatrick }
6600e5dd7070Spatrick
6601e5dd7070Spatrick // C++11 [expr.cond]p3
6602e5dd7070Spatrick // if both are glvalues of the same value category and the same type except
6603e5dd7070Spatrick // for cv-qualification, an attempt is made to convert each of those
6604e5dd7070Spatrick // operands to the type of the other.
6605e5dd7070Spatrick // FIXME:
6606e5dd7070Spatrick // Resolving a defect in P0012R1: we extend this to cover all cases where
6607e5dd7070Spatrick // one of the operands is reference-compatible with the other, in order
6608e5dd7070Spatrick // to support conditionals between functions differing in noexcept. This
6609e5dd7070Spatrick // will similarly cover difference in array bounds after P0388R4.
6610e5dd7070Spatrick // FIXME: If LTy and RTy have a composite pointer type, should we convert to
6611e5dd7070Spatrick // that instead?
6612e5dd7070Spatrick ExprValueKind LVK = LHS.get()->getValueKind();
6613e5dd7070Spatrick ExprValueKind RVK = RHS.get()->getValueKind();
6614a9ac8606Spatrick if (!Context.hasSameType(LTy, RTy) && LVK == RVK && LVK != VK_PRValue) {
6615e5dd7070Spatrick // DerivedToBase was already handled by the class-specific case above.
6616e5dd7070Spatrick // FIXME: Should we allow ObjC conversions here?
6617e5dd7070Spatrick const ReferenceConversions AllowedConversions =
6618e5dd7070Spatrick ReferenceConversions::Qualification |
6619e5dd7070Spatrick ReferenceConversions::NestedQualification |
6620e5dd7070Spatrick ReferenceConversions::Function;
6621e5dd7070Spatrick
6622e5dd7070Spatrick ReferenceConversions RefConv;
6623e5dd7070Spatrick if (CompareReferenceRelationship(QuestionLoc, LTy, RTy, &RefConv) ==
6624e5dd7070Spatrick Ref_Compatible &&
6625e5dd7070Spatrick !(RefConv & ~AllowedConversions) &&
6626e5dd7070Spatrick // [...] subject to the constraint that the reference must bind
6627e5dd7070Spatrick // directly [...]
6628e5dd7070Spatrick !RHS.get()->refersToBitField() && !RHS.get()->refersToVectorElement()) {
6629e5dd7070Spatrick RHS = ImpCastExprToType(RHS.get(), LTy, CK_NoOp, RVK);
6630e5dd7070Spatrick RTy = RHS.get()->getType();
6631e5dd7070Spatrick } else if (CompareReferenceRelationship(QuestionLoc, RTy, LTy, &RefConv) ==
6632e5dd7070Spatrick Ref_Compatible &&
6633e5dd7070Spatrick !(RefConv & ~AllowedConversions) &&
6634e5dd7070Spatrick !LHS.get()->refersToBitField() &&
6635e5dd7070Spatrick !LHS.get()->refersToVectorElement()) {
6636e5dd7070Spatrick LHS = ImpCastExprToType(LHS.get(), RTy, CK_NoOp, LVK);
6637e5dd7070Spatrick LTy = LHS.get()->getType();
6638e5dd7070Spatrick }
6639e5dd7070Spatrick }
6640e5dd7070Spatrick
6641e5dd7070Spatrick // C++11 [expr.cond]p4
6642e5dd7070Spatrick // If the second and third operands are glvalues of the same value
6643e5dd7070Spatrick // category and have the same type, the result is of that type and
6644e5dd7070Spatrick // value category and it is a bit-field if the second or the third
6645e5dd7070Spatrick // operand is a bit-field, or if both are bit-fields.
6646e5dd7070Spatrick // We only extend this to bitfields, not to the crazy other kinds of
6647e5dd7070Spatrick // l-values.
6648e5dd7070Spatrick bool Same = Context.hasSameType(LTy, RTy);
6649a9ac8606Spatrick if (Same && LVK == RVK && LVK != VK_PRValue &&
6650e5dd7070Spatrick LHS.get()->isOrdinaryOrBitFieldObject() &&
6651e5dd7070Spatrick RHS.get()->isOrdinaryOrBitFieldObject()) {
6652e5dd7070Spatrick VK = LHS.get()->getValueKind();
6653e5dd7070Spatrick if (LHS.get()->getObjectKind() == OK_BitField ||
6654e5dd7070Spatrick RHS.get()->getObjectKind() == OK_BitField)
6655e5dd7070Spatrick OK = OK_BitField;
6656*12c85518Srobert return Context.getCommonSugaredType(LTy, RTy);
6657e5dd7070Spatrick }
6658e5dd7070Spatrick
6659e5dd7070Spatrick // C++11 [expr.cond]p5
6660e5dd7070Spatrick // Otherwise, the result is a prvalue. If the second and third operands
6661e5dd7070Spatrick // do not have the same type, and either has (cv) class type, ...
6662e5dd7070Spatrick if (!Same && (LTy->isRecordType() || RTy->isRecordType())) {
6663e5dd7070Spatrick // ... overload resolution is used to determine the conversions (if any)
6664e5dd7070Spatrick // to be applied to the operands. If the overload resolution fails, the
6665e5dd7070Spatrick // program is ill-formed.
6666e5dd7070Spatrick if (FindConditionalOverload(*this, LHS, RHS, QuestionLoc))
6667e5dd7070Spatrick return QualType();
6668e5dd7070Spatrick }
6669e5dd7070Spatrick
6670e5dd7070Spatrick // C++11 [expr.cond]p6
6671e5dd7070Spatrick // Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard
6672e5dd7070Spatrick // conversions are performed on the second and third operands.
6673e5dd7070Spatrick LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
6674e5dd7070Spatrick RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
6675e5dd7070Spatrick if (LHS.isInvalid() || RHS.isInvalid())
6676e5dd7070Spatrick return QualType();
6677e5dd7070Spatrick LTy = LHS.get()->getType();
6678e5dd7070Spatrick RTy = RHS.get()->getType();
6679e5dd7070Spatrick
6680e5dd7070Spatrick // After those conversions, one of the following shall hold:
6681e5dd7070Spatrick // -- The second and third operands have the same type; the result
6682e5dd7070Spatrick // is of that type. If the operands have class type, the result
6683e5dd7070Spatrick // is a prvalue temporary of the result type, which is
6684e5dd7070Spatrick // copy-initialized from either the second operand or the third
6685e5dd7070Spatrick // operand depending on the value of the first operand.
6686*12c85518Srobert if (Context.hasSameType(LTy, RTy)) {
6687e5dd7070Spatrick if (LTy->isRecordType()) {
6688e5dd7070Spatrick // The operands have class type. Make a temporary copy.
6689*12c85518Srobert ExprResult LHSCopy = PerformCopyInitialization(
6690*12c85518Srobert InitializedEntity::InitializeTemporary(LTy), SourceLocation(), LHS);
6691e5dd7070Spatrick if (LHSCopy.isInvalid())
6692e5dd7070Spatrick return QualType();
6693e5dd7070Spatrick
6694*12c85518Srobert ExprResult RHSCopy = PerformCopyInitialization(
6695*12c85518Srobert InitializedEntity::InitializeTemporary(RTy), SourceLocation(), RHS);
6696e5dd7070Spatrick if (RHSCopy.isInvalid())
6697e5dd7070Spatrick return QualType();
6698e5dd7070Spatrick
6699e5dd7070Spatrick LHS = LHSCopy;
6700e5dd7070Spatrick RHS = RHSCopy;
6701e5dd7070Spatrick }
6702*12c85518Srobert return Context.getCommonSugaredType(LTy, RTy);
6703e5dd7070Spatrick }
6704e5dd7070Spatrick
6705e5dd7070Spatrick // Extension: conditional operator involving vector types.
6706e5dd7070Spatrick if (LTy->isVectorType() || RTy->isVectorType())
6707e5dd7070Spatrick return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/ false,
6708e5dd7070Spatrick /*AllowBothBool*/ true,
6709*12c85518Srobert /*AllowBoolConversions*/ false,
6710*12c85518Srobert /*AllowBoolOperation*/ false,
6711*12c85518Srobert /*ReportInvalid*/ true);
6712e5dd7070Spatrick
6713e5dd7070Spatrick // -- The second and third operands have arithmetic or enumeration type;
6714e5dd7070Spatrick // the usual arithmetic conversions are performed to bring them to a
6715e5dd7070Spatrick // common type, and the result is of that type.
6716e5dd7070Spatrick if (LTy->isArithmeticType() && RTy->isArithmeticType()) {
6717e5dd7070Spatrick QualType ResTy =
6718e5dd7070Spatrick UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional);
6719e5dd7070Spatrick if (LHS.isInvalid() || RHS.isInvalid())
6720e5dd7070Spatrick return QualType();
6721e5dd7070Spatrick if (ResTy.isNull()) {
6722e5dd7070Spatrick Diag(QuestionLoc,
6723e5dd7070Spatrick diag::err_typecheck_cond_incompatible_operands) << LTy << RTy
6724e5dd7070Spatrick << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
6725e5dd7070Spatrick return QualType();
6726e5dd7070Spatrick }
6727e5dd7070Spatrick
6728e5dd7070Spatrick LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy));
6729e5dd7070Spatrick RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy));
6730e5dd7070Spatrick
6731e5dd7070Spatrick return ResTy;
6732e5dd7070Spatrick }
6733e5dd7070Spatrick
6734e5dd7070Spatrick // -- The second and third operands have pointer type, or one has pointer
6735e5dd7070Spatrick // type and the other is a null pointer constant, or both are null
6736e5dd7070Spatrick // pointer constants, at least one of which is non-integral; pointer
6737e5dd7070Spatrick // conversions and qualification conversions are performed to bring them
6738e5dd7070Spatrick // to their composite pointer type. The result is of the composite
6739e5dd7070Spatrick // pointer type.
6740e5dd7070Spatrick // -- The second and third operands have pointer to member type, or one has
6741e5dd7070Spatrick // pointer to member type and the other is a null pointer constant;
6742e5dd7070Spatrick // pointer to member conversions and qualification conversions are
6743e5dd7070Spatrick // performed to bring them to a common type, whose cv-qualification
6744e5dd7070Spatrick // shall match the cv-qualification of either the second or the third
6745e5dd7070Spatrick // operand. The result is of the common type.
6746e5dd7070Spatrick QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS);
6747e5dd7070Spatrick if (!Composite.isNull())
6748e5dd7070Spatrick return Composite;
6749e5dd7070Spatrick
6750e5dd7070Spatrick // Similarly, attempt to find composite type of two objective-c pointers.
6751e5dd7070Spatrick Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc);
6752a9ac8606Spatrick if (LHS.isInvalid() || RHS.isInvalid())
6753a9ac8606Spatrick return QualType();
6754e5dd7070Spatrick if (!Composite.isNull())
6755e5dd7070Spatrick return Composite;
6756e5dd7070Spatrick
6757e5dd7070Spatrick // Check if we are using a null with a non-pointer type.
6758e5dd7070Spatrick if (DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc))
6759e5dd7070Spatrick return QualType();
6760e5dd7070Spatrick
6761e5dd7070Spatrick Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
6762e5dd7070Spatrick << LHS.get()->getType() << RHS.get()->getType()
6763e5dd7070Spatrick << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
6764e5dd7070Spatrick return QualType();
6765e5dd7070Spatrick }
6766e5dd7070Spatrick
6767e5dd7070Spatrick /// Find a merged pointer type and convert the two expressions to it.
6768e5dd7070Spatrick ///
6769e5dd7070Spatrick /// This finds the composite pointer type for \p E1 and \p E2 according to
6770e5dd7070Spatrick /// C++2a [expr.type]p3. It converts both expressions to this type and returns
6771e5dd7070Spatrick /// it. It does not emit diagnostics (FIXME: that's not true if \p ConvertArgs
6772e5dd7070Spatrick /// is \c true).
6773e5dd7070Spatrick ///
6774e5dd7070Spatrick /// \param Loc The location of the operator requiring these two expressions to
6775e5dd7070Spatrick /// be converted to the composite pointer type.
6776e5dd7070Spatrick ///
6777e5dd7070Spatrick /// \param ConvertArgs If \c false, do not convert E1 and E2 to the target type.
FindCompositePointerType(SourceLocation Loc,Expr * & E1,Expr * & E2,bool ConvertArgs)6778e5dd7070Spatrick QualType Sema::FindCompositePointerType(SourceLocation Loc,
6779e5dd7070Spatrick Expr *&E1, Expr *&E2,
6780e5dd7070Spatrick bool ConvertArgs) {
6781e5dd7070Spatrick assert(getLangOpts().CPlusPlus && "This function assumes C++");
6782e5dd7070Spatrick
6783e5dd7070Spatrick // C++1z [expr]p14:
6784e5dd7070Spatrick // The composite pointer type of two operands p1 and p2 having types T1
6785e5dd7070Spatrick // and T2
6786e5dd7070Spatrick QualType T1 = E1->getType(), T2 = E2->getType();
6787e5dd7070Spatrick
6788e5dd7070Spatrick // where at least one is a pointer or pointer to member type or
6789e5dd7070Spatrick // std::nullptr_t is:
6790e5dd7070Spatrick bool T1IsPointerLike = T1->isAnyPointerType() || T1->isMemberPointerType() ||
6791e5dd7070Spatrick T1->isNullPtrType();
6792e5dd7070Spatrick bool T2IsPointerLike = T2->isAnyPointerType() || T2->isMemberPointerType() ||
6793e5dd7070Spatrick T2->isNullPtrType();
6794e5dd7070Spatrick if (!T1IsPointerLike && !T2IsPointerLike)
6795e5dd7070Spatrick return QualType();
6796e5dd7070Spatrick
6797e5dd7070Spatrick // - if both p1 and p2 are null pointer constants, std::nullptr_t;
6798e5dd7070Spatrick // This can't actually happen, following the standard, but we also use this
6799e5dd7070Spatrick // to implement the end of [expr.conv], which hits this case.
6800e5dd7070Spatrick //
6801e5dd7070Spatrick // - if either p1 or p2 is a null pointer constant, T2 or T1, respectively;
6802e5dd7070Spatrick if (T1IsPointerLike &&
6803e5dd7070Spatrick E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
6804e5dd7070Spatrick if (ConvertArgs)
6805e5dd7070Spatrick E2 = ImpCastExprToType(E2, T1, T1->isMemberPointerType()
6806e5dd7070Spatrick ? CK_NullToMemberPointer
6807e5dd7070Spatrick : CK_NullToPointer).get();
6808e5dd7070Spatrick return T1;
6809e5dd7070Spatrick }
6810e5dd7070Spatrick if (T2IsPointerLike &&
6811e5dd7070Spatrick E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
6812e5dd7070Spatrick if (ConvertArgs)
6813e5dd7070Spatrick E1 = ImpCastExprToType(E1, T2, T2->isMemberPointerType()
6814e5dd7070Spatrick ? CK_NullToMemberPointer
6815e5dd7070Spatrick : CK_NullToPointer).get();
6816e5dd7070Spatrick return T2;
6817e5dd7070Spatrick }
6818e5dd7070Spatrick
6819e5dd7070Spatrick // Now both have to be pointers or member pointers.
6820e5dd7070Spatrick if (!T1IsPointerLike || !T2IsPointerLike)
6821e5dd7070Spatrick return QualType();
6822e5dd7070Spatrick assert(!T1->isNullPtrType() && !T2->isNullPtrType() &&
6823e5dd7070Spatrick "nullptr_t should be a null pointer constant");
6824e5dd7070Spatrick
6825e5dd7070Spatrick struct Step {
6826e5dd7070Spatrick enum Kind { Pointer, ObjCPointer, MemberPointer, Array } K;
6827e5dd7070Spatrick // Qualifiers to apply under the step kind.
6828e5dd7070Spatrick Qualifiers Quals;
6829e5dd7070Spatrick /// The class for a pointer-to-member; a constant array type with a bound
6830e5dd7070Spatrick /// (if any) for an array.
6831e5dd7070Spatrick const Type *ClassOrBound;
6832e5dd7070Spatrick
6833e5dd7070Spatrick Step(Kind K, const Type *ClassOrBound = nullptr)
6834*12c85518Srobert : K(K), ClassOrBound(ClassOrBound) {}
6835e5dd7070Spatrick QualType rebuild(ASTContext &Ctx, QualType T) const {
6836e5dd7070Spatrick T = Ctx.getQualifiedType(T, Quals);
6837e5dd7070Spatrick switch (K) {
6838e5dd7070Spatrick case Pointer:
6839e5dd7070Spatrick return Ctx.getPointerType(T);
6840e5dd7070Spatrick case MemberPointer:
6841e5dd7070Spatrick return Ctx.getMemberPointerType(T, ClassOrBound);
6842e5dd7070Spatrick case ObjCPointer:
6843e5dd7070Spatrick return Ctx.getObjCObjectPointerType(T);
6844e5dd7070Spatrick case Array:
6845e5dd7070Spatrick if (auto *CAT = cast_or_null<ConstantArrayType>(ClassOrBound))
6846e5dd7070Spatrick return Ctx.getConstantArrayType(T, CAT->getSize(), nullptr,
6847e5dd7070Spatrick ArrayType::Normal, 0);
6848e5dd7070Spatrick else
6849e5dd7070Spatrick return Ctx.getIncompleteArrayType(T, ArrayType::Normal, 0);
6850e5dd7070Spatrick }
6851e5dd7070Spatrick llvm_unreachable("unknown step kind");
6852e5dd7070Spatrick }
6853e5dd7070Spatrick };
6854e5dd7070Spatrick
6855e5dd7070Spatrick SmallVector<Step, 8> Steps;
6856e5dd7070Spatrick
6857e5dd7070Spatrick // - if T1 is "pointer to cv1 C1" and T2 is "pointer to cv2 C2", where C1
6858e5dd7070Spatrick // is reference-related to C2 or C2 is reference-related to C1 (8.6.3),
6859e5dd7070Spatrick // the cv-combined type of T1 and T2 or the cv-combined type of T2 and T1,
6860e5dd7070Spatrick // respectively;
6861e5dd7070Spatrick // - if T1 is "pointer to member of C1 of type cv1 U1" and T2 is "pointer
6862e5dd7070Spatrick // to member of C2 of type cv2 U2" for some non-function type U, where
6863e5dd7070Spatrick // C1 is reference-related to C2 or C2 is reference-related to C1, the
6864e5dd7070Spatrick // cv-combined type of T2 and T1 or the cv-combined type of T1 and T2,
6865e5dd7070Spatrick // respectively;
6866e5dd7070Spatrick // - if T1 and T2 are similar types (4.5), the cv-combined type of T1 and
6867e5dd7070Spatrick // T2;
6868e5dd7070Spatrick //
6869e5dd7070Spatrick // Dismantle T1 and T2 to simultaneously determine whether they are similar
6870e5dd7070Spatrick // and to prepare to form the cv-combined type if so.
6871e5dd7070Spatrick QualType Composite1 = T1;
6872e5dd7070Spatrick QualType Composite2 = T2;
6873e5dd7070Spatrick unsigned NeedConstBefore = 0;
6874e5dd7070Spatrick while (true) {
6875e5dd7070Spatrick assert(!Composite1.isNull() && !Composite2.isNull());
6876e5dd7070Spatrick
6877e5dd7070Spatrick Qualifiers Q1, Q2;
6878e5dd7070Spatrick Composite1 = Context.getUnqualifiedArrayType(Composite1, Q1);
6879e5dd7070Spatrick Composite2 = Context.getUnqualifiedArrayType(Composite2, Q2);
6880e5dd7070Spatrick
6881e5dd7070Spatrick // Top-level qualifiers are ignored. Merge at all lower levels.
6882e5dd7070Spatrick if (!Steps.empty()) {
6883e5dd7070Spatrick // Find the qualifier union: (approximately) the unique minimal set of
6884e5dd7070Spatrick // qualifiers that is compatible with both types.
6885e5dd7070Spatrick Qualifiers Quals = Qualifiers::fromCVRUMask(Q1.getCVRUQualifiers() |
6886e5dd7070Spatrick Q2.getCVRUQualifiers());
6887e5dd7070Spatrick
6888e5dd7070Spatrick // Under one level of pointer or pointer-to-member, we can change to an
6889e5dd7070Spatrick // unambiguous compatible address space.
6890e5dd7070Spatrick if (Q1.getAddressSpace() == Q2.getAddressSpace()) {
6891e5dd7070Spatrick Quals.setAddressSpace(Q1.getAddressSpace());
6892e5dd7070Spatrick } else if (Steps.size() == 1) {
6893e5dd7070Spatrick bool MaybeQ1 = Q1.isAddressSpaceSupersetOf(Q2);
6894e5dd7070Spatrick bool MaybeQ2 = Q2.isAddressSpaceSupersetOf(Q1);
6895*12c85518Srobert if (MaybeQ1 == MaybeQ2) {
6896*12c85518Srobert // Exception for ptr size address spaces. Should be able to choose
6897*12c85518Srobert // either address space during comparison.
6898*12c85518Srobert if (isPtrSizeAddressSpace(Q1.getAddressSpace()) ||
6899*12c85518Srobert isPtrSizeAddressSpace(Q2.getAddressSpace()))
6900*12c85518Srobert MaybeQ1 = true;
6901*12c85518Srobert else
6902e5dd7070Spatrick return QualType(); // No unique best address space.
6903*12c85518Srobert }
6904e5dd7070Spatrick Quals.setAddressSpace(MaybeQ1 ? Q1.getAddressSpace()
6905e5dd7070Spatrick : Q2.getAddressSpace());
6906e5dd7070Spatrick } else {
6907e5dd7070Spatrick return QualType();
6908e5dd7070Spatrick }
6909e5dd7070Spatrick
6910e5dd7070Spatrick // FIXME: In C, we merge __strong and none to __strong at the top level.
6911e5dd7070Spatrick if (Q1.getObjCGCAttr() == Q2.getObjCGCAttr())
6912e5dd7070Spatrick Quals.setObjCGCAttr(Q1.getObjCGCAttr());
6913a9ac8606Spatrick else if (T1->isVoidPointerType() || T2->isVoidPointerType())
6914a9ac8606Spatrick assert(Steps.size() == 1);
6915e5dd7070Spatrick else
6916e5dd7070Spatrick return QualType();
6917e5dd7070Spatrick
6918e5dd7070Spatrick // Mismatched lifetime qualifiers never compatibly include each other.
6919e5dd7070Spatrick if (Q1.getObjCLifetime() == Q2.getObjCLifetime())
6920e5dd7070Spatrick Quals.setObjCLifetime(Q1.getObjCLifetime());
6921a9ac8606Spatrick else if (T1->isVoidPointerType() || T2->isVoidPointerType())
6922a9ac8606Spatrick assert(Steps.size() == 1);
6923e5dd7070Spatrick else
6924e5dd7070Spatrick return QualType();
6925e5dd7070Spatrick
6926e5dd7070Spatrick Steps.back().Quals = Quals;
6927e5dd7070Spatrick if (Q1 != Quals || Q2 != Quals)
6928e5dd7070Spatrick NeedConstBefore = Steps.size() - 1;
6929e5dd7070Spatrick }
6930e5dd7070Spatrick
6931e5dd7070Spatrick // FIXME: Can we unify the following with UnwrapSimilarTypes?
6932*12c85518Srobert
6933*12c85518Srobert const ArrayType *Arr1, *Arr2;
6934*12c85518Srobert if ((Arr1 = Context.getAsArrayType(Composite1)) &&
6935*12c85518Srobert (Arr2 = Context.getAsArrayType(Composite2))) {
6936*12c85518Srobert auto *CAT1 = dyn_cast<ConstantArrayType>(Arr1);
6937*12c85518Srobert auto *CAT2 = dyn_cast<ConstantArrayType>(Arr2);
6938*12c85518Srobert if (CAT1 && CAT2 && CAT1->getSize() == CAT2->getSize()) {
6939*12c85518Srobert Composite1 = Arr1->getElementType();
6940*12c85518Srobert Composite2 = Arr2->getElementType();
6941*12c85518Srobert Steps.emplace_back(Step::Array, CAT1);
6942*12c85518Srobert continue;
6943*12c85518Srobert }
6944*12c85518Srobert bool IAT1 = isa<IncompleteArrayType>(Arr1);
6945*12c85518Srobert bool IAT2 = isa<IncompleteArrayType>(Arr2);
6946*12c85518Srobert if ((IAT1 && IAT2) ||
6947*12c85518Srobert (getLangOpts().CPlusPlus20 && (IAT1 != IAT2) &&
6948*12c85518Srobert ((bool)CAT1 != (bool)CAT2) &&
6949*12c85518Srobert (Steps.empty() || Steps.back().K != Step::Array))) {
6950*12c85518Srobert // In C++20 onwards, we can unify an array of N T with an array of
6951*12c85518Srobert // a different or unknown bound. But we can't form an array whose
6952*12c85518Srobert // element type is an array of unknown bound by doing so.
6953*12c85518Srobert Composite1 = Arr1->getElementType();
6954*12c85518Srobert Composite2 = Arr2->getElementType();
6955*12c85518Srobert Steps.emplace_back(Step::Array);
6956*12c85518Srobert if (CAT1 || CAT2)
6957*12c85518Srobert NeedConstBefore = Steps.size();
6958*12c85518Srobert continue;
6959*12c85518Srobert }
6960*12c85518Srobert }
6961*12c85518Srobert
6962e5dd7070Spatrick const PointerType *Ptr1, *Ptr2;
6963e5dd7070Spatrick if ((Ptr1 = Composite1->getAs<PointerType>()) &&
6964e5dd7070Spatrick (Ptr2 = Composite2->getAs<PointerType>())) {
6965e5dd7070Spatrick Composite1 = Ptr1->getPointeeType();
6966e5dd7070Spatrick Composite2 = Ptr2->getPointeeType();
6967e5dd7070Spatrick Steps.emplace_back(Step::Pointer);
6968e5dd7070Spatrick continue;
6969e5dd7070Spatrick }
6970e5dd7070Spatrick
6971e5dd7070Spatrick const ObjCObjectPointerType *ObjPtr1, *ObjPtr2;
6972e5dd7070Spatrick if ((ObjPtr1 = Composite1->getAs<ObjCObjectPointerType>()) &&
6973e5dd7070Spatrick (ObjPtr2 = Composite2->getAs<ObjCObjectPointerType>())) {
6974e5dd7070Spatrick Composite1 = ObjPtr1->getPointeeType();
6975e5dd7070Spatrick Composite2 = ObjPtr2->getPointeeType();
6976e5dd7070Spatrick Steps.emplace_back(Step::ObjCPointer);
6977e5dd7070Spatrick continue;
6978e5dd7070Spatrick }
6979e5dd7070Spatrick
6980e5dd7070Spatrick const MemberPointerType *MemPtr1, *MemPtr2;
6981e5dd7070Spatrick if ((MemPtr1 = Composite1->getAs<MemberPointerType>()) &&
6982e5dd7070Spatrick (MemPtr2 = Composite2->getAs<MemberPointerType>())) {
6983e5dd7070Spatrick Composite1 = MemPtr1->getPointeeType();
6984e5dd7070Spatrick Composite2 = MemPtr2->getPointeeType();
6985e5dd7070Spatrick
6986e5dd7070Spatrick // At the top level, we can perform a base-to-derived pointer-to-member
6987e5dd7070Spatrick // conversion:
6988e5dd7070Spatrick //
6989e5dd7070Spatrick // - [...] where C1 is reference-related to C2 or C2 is
6990e5dd7070Spatrick // reference-related to C1
6991e5dd7070Spatrick //
6992e5dd7070Spatrick // (Note that the only kinds of reference-relatedness in scope here are
6993e5dd7070Spatrick // "same type or derived from".) At any other level, the class must
6994e5dd7070Spatrick // exactly match.
6995e5dd7070Spatrick const Type *Class = nullptr;
6996e5dd7070Spatrick QualType Cls1(MemPtr1->getClass(), 0);
6997e5dd7070Spatrick QualType Cls2(MemPtr2->getClass(), 0);
6998e5dd7070Spatrick if (Context.hasSameType(Cls1, Cls2))
6999e5dd7070Spatrick Class = MemPtr1->getClass();
7000e5dd7070Spatrick else if (Steps.empty())
7001e5dd7070Spatrick Class = IsDerivedFrom(Loc, Cls1, Cls2) ? MemPtr1->getClass() :
7002e5dd7070Spatrick IsDerivedFrom(Loc, Cls2, Cls1) ? MemPtr2->getClass() : nullptr;
7003e5dd7070Spatrick if (!Class)
7004e5dd7070Spatrick return QualType();
7005e5dd7070Spatrick
7006e5dd7070Spatrick Steps.emplace_back(Step::MemberPointer, Class);
7007e5dd7070Spatrick continue;
7008e5dd7070Spatrick }
7009e5dd7070Spatrick
7010e5dd7070Spatrick // Special case: at the top level, we can decompose an Objective-C pointer
7011e5dd7070Spatrick // and a 'cv void *'. Unify the qualifiers.
7012e5dd7070Spatrick if (Steps.empty() && ((Composite1->isVoidPointerType() &&
7013e5dd7070Spatrick Composite2->isObjCObjectPointerType()) ||
7014e5dd7070Spatrick (Composite1->isObjCObjectPointerType() &&
7015e5dd7070Spatrick Composite2->isVoidPointerType()))) {
7016e5dd7070Spatrick Composite1 = Composite1->getPointeeType();
7017e5dd7070Spatrick Composite2 = Composite2->getPointeeType();
7018e5dd7070Spatrick Steps.emplace_back(Step::Pointer);
7019e5dd7070Spatrick continue;
7020e5dd7070Spatrick }
7021e5dd7070Spatrick
7022e5dd7070Spatrick // FIXME: block pointer types?
7023e5dd7070Spatrick
7024e5dd7070Spatrick // Cannot unwrap any more types.
7025e5dd7070Spatrick break;
7026e5dd7070Spatrick }
7027e5dd7070Spatrick
7028e5dd7070Spatrick // - if T1 or T2 is "pointer to noexcept function" and the other type is
7029e5dd7070Spatrick // "pointer to function", where the function types are otherwise the same,
7030e5dd7070Spatrick // "pointer to function";
7031e5dd7070Spatrick // - if T1 or T2 is "pointer to member of C1 of type function", the other
7032e5dd7070Spatrick // type is "pointer to member of C2 of type noexcept function", and C1
7033e5dd7070Spatrick // is reference-related to C2 or C2 is reference-related to C1, where
7034e5dd7070Spatrick // the function types are otherwise the same, "pointer to member of C2 of
7035e5dd7070Spatrick // type function" or "pointer to member of C1 of type function",
7036e5dd7070Spatrick // respectively;
7037e5dd7070Spatrick //
7038e5dd7070Spatrick // We also support 'noreturn' here, so as a Clang extension we generalize the
7039e5dd7070Spatrick // above to:
7040e5dd7070Spatrick //
7041e5dd7070Spatrick // - [Clang] If T1 and T2 are both of type "pointer to function" or
7042e5dd7070Spatrick // "pointer to member function" and the pointee types can be unified
7043e5dd7070Spatrick // by a function pointer conversion, that conversion is applied
7044e5dd7070Spatrick // before checking the following rules.
7045e5dd7070Spatrick //
7046e5dd7070Spatrick // We've already unwrapped down to the function types, and we want to merge
7047e5dd7070Spatrick // rather than just convert, so do this ourselves rather than calling
7048e5dd7070Spatrick // IsFunctionConversion.
7049e5dd7070Spatrick //
7050e5dd7070Spatrick // FIXME: In order to match the standard wording as closely as possible, we
7051e5dd7070Spatrick // currently only do this under a single level of pointers. Ideally, we would
7052e5dd7070Spatrick // allow this in general, and set NeedConstBefore to the relevant depth on
7053e5dd7070Spatrick // the side(s) where we changed anything. If we permit that, we should also
7054e5dd7070Spatrick // consider this conversion when determining type similarity and model it as
7055e5dd7070Spatrick // a qualification conversion.
7056e5dd7070Spatrick if (Steps.size() == 1) {
7057e5dd7070Spatrick if (auto *FPT1 = Composite1->getAs<FunctionProtoType>()) {
7058e5dd7070Spatrick if (auto *FPT2 = Composite2->getAs<FunctionProtoType>()) {
7059e5dd7070Spatrick FunctionProtoType::ExtProtoInfo EPI1 = FPT1->getExtProtoInfo();
7060e5dd7070Spatrick FunctionProtoType::ExtProtoInfo EPI2 = FPT2->getExtProtoInfo();
7061e5dd7070Spatrick
7062e5dd7070Spatrick // The result is noreturn if both operands are.
7063e5dd7070Spatrick bool Noreturn =
7064e5dd7070Spatrick EPI1.ExtInfo.getNoReturn() && EPI2.ExtInfo.getNoReturn();
7065e5dd7070Spatrick EPI1.ExtInfo = EPI1.ExtInfo.withNoReturn(Noreturn);
7066e5dd7070Spatrick EPI2.ExtInfo = EPI2.ExtInfo.withNoReturn(Noreturn);
7067e5dd7070Spatrick
7068e5dd7070Spatrick // The result is nothrow if both operands are.
7069e5dd7070Spatrick SmallVector<QualType, 8> ExceptionTypeStorage;
7070*12c85518Srobert EPI1.ExceptionSpec = EPI2.ExceptionSpec = Context.mergeExceptionSpecs(
7071*12c85518Srobert EPI1.ExceptionSpec, EPI2.ExceptionSpec, ExceptionTypeStorage,
7072*12c85518Srobert getLangOpts().CPlusPlus17);
7073e5dd7070Spatrick
7074e5dd7070Spatrick Composite1 = Context.getFunctionType(FPT1->getReturnType(),
7075e5dd7070Spatrick FPT1->getParamTypes(), EPI1);
7076e5dd7070Spatrick Composite2 = Context.getFunctionType(FPT2->getReturnType(),
7077e5dd7070Spatrick FPT2->getParamTypes(), EPI2);
7078e5dd7070Spatrick }
7079e5dd7070Spatrick }
7080e5dd7070Spatrick }
7081e5dd7070Spatrick
7082e5dd7070Spatrick // There are some more conversions we can perform under exactly one pointer.
7083e5dd7070Spatrick if (Steps.size() == 1 && Steps.front().K == Step::Pointer &&
7084e5dd7070Spatrick !Context.hasSameType(Composite1, Composite2)) {
7085e5dd7070Spatrick // - if T1 or T2 is "pointer to cv1 void" and the other type is
7086e5dd7070Spatrick // "pointer to cv2 T", where T is an object type or void,
7087e5dd7070Spatrick // "pointer to cv12 void", where cv12 is the union of cv1 and cv2;
7088e5dd7070Spatrick if (Composite1->isVoidType() && Composite2->isObjectType())
7089e5dd7070Spatrick Composite2 = Composite1;
7090e5dd7070Spatrick else if (Composite2->isVoidType() && Composite1->isObjectType())
7091e5dd7070Spatrick Composite1 = Composite2;
7092e5dd7070Spatrick // - if T1 is "pointer to cv1 C1" and T2 is "pointer to cv2 C2", where C1
7093e5dd7070Spatrick // is reference-related to C2 or C2 is reference-related to C1 (8.6.3),
7094e5dd7070Spatrick // the cv-combined type of T1 and T2 or the cv-combined type of T2 and
7095e5dd7070Spatrick // T1, respectively;
7096e5dd7070Spatrick //
7097e5dd7070Spatrick // The "similar type" handling covers all of this except for the "T1 is a
7098e5dd7070Spatrick // base class of T2" case in the definition of reference-related.
7099e5dd7070Spatrick else if (IsDerivedFrom(Loc, Composite1, Composite2))
7100e5dd7070Spatrick Composite1 = Composite2;
7101e5dd7070Spatrick else if (IsDerivedFrom(Loc, Composite2, Composite1))
7102e5dd7070Spatrick Composite2 = Composite1;
7103e5dd7070Spatrick }
7104e5dd7070Spatrick
7105e5dd7070Spatrick // At this point, either the inner types are the same or we have failed to
7106e5dd7070Spatrick // find a composite pointer type.
7107e5dd7070Spatrick if (!Context.hasSameType(Composite1, Composite2))
7108e5dd7070Spatrick return QualType();
7109e5dd7070Spatrick
7110e5dd7070Spatrick // Per C++ [conv.qual]p3, add 'const' to every level before the last
7111e5dd7070Spatrick // differing qualifier.
7112e5dd7070Spatrick for (unsigned I = 0; I != NeedConstBefore; ++I)
7113e5dd7070Spatrick Steps[I].Quals.addConst();
7114e5dd7070Spatrick
7115e5dd7070Spatrick // Rebuild the composite type.
7116*12c85518Srobert QualType Composite = Context.getCommonSugaredType(Composite1, Composite2);
7117e5dd7070Spatrick for (auto &S : llvm::reverse(Steps))
7118e5dd7070Spatrick Composite = S.rebuild(Context, Composite);
7119e5dd7070Spatrick
7120e5dd7070Spatrick if (ConvertArgs) {
7121e5dd7070Spatrick // Convert the expressions to the composite pointer type.
7122e5dd7070Spatrick InitializedEntity Entity =
7123e5dd7070Spatrick InitializedEntity::InitializeTemporary(Composite);
7124e5dd7070Spatrick InitializationKind Kind =
7125e5dd7070Spatrick InitializationKind::CreateCopy(Loc, SourceLocation());
7126e5dd7070Spatrick
7127e5dd7070Spatrick InitializationSequence E1ToC(*this, Entity, Kind, E1);
7128e5dd7070Spatrick if (!E1ToC)
7129e5dd7070Spatrick return QualType();
7130e5dd7070Spatrick
7131e5dd7070Spatrick InitializationSequence E2ToC(*this, Entity, Kind, E2);
7132e5dd7070Spatrick if (!E2ToC)
7133e5dd7070Spatrick return QualType();
7134e5dd7070Spatrick
7135e5dd7070Spatrick // FIXME: Let the caller know if these fail to avoid duplicate diagnostics.
7136e5dd7070Spatrick ExprResult E1Result = E1ToC.Perform(*this, Entity, Kind, E1);
7137e5dd7070Spatrick if (E1Result.isInvalid())
7138e5dd7070Spatrick return QualType();
7139e5dd7070Spatrick E1 = E1Result.get();
7140e5dd7070Spatrick
7141e5dd7070Spatrick ExprResult E2Result = E2ToC.Perform(*this, Entity, Kind, E2);
7142e5dd7070Spatrick if (E2Result.isInvalid())
7143e5dd7070Spatrick return QualType();
7144e5dd7070Spatrick E2 = E2Result.get();
7145e5dd7070Spatrick }
7146e5dd7070Spatrick
7147e5dd7070Spatrick return Composite;
7148e5dd7070Spatrick }
7149e5dd7070Spatrick
MaybeBindToTemporary(Expr * E)7150e5dd7070Spatrick ExprResult Sema::MaybeBindToTemporary(Expr *E) {
7151e5dd7070Spatrick if (!E)
7152e5dd7070Spatrick return ExprError();
7153e5dd7070Spatrick
7154e5dd7070Spatrick assert(!isa<CXXBindTemporaryExpr>(E) && "Double-bound temporary?");
7155e5dd7070Spatrick
7156e5dd7070Spatrick // If the result is a glvalue, we shouldn't bind it.
7157a9ac8606Spatrick if (E->isGLValue())
7158e5dd7070Spatrick return E;
7159e5dd7070Spatrick
7160e5dd7070Spatrick // In ARC, calls that return a retainable type can return retained,
7161e5dd7070Spatrick // in which case we have to insert a consuming cast.
7162e5dd7070Spatrick if (getLangOpts().ObjCAutoRefCount &&
7163e5dd7070Spatrick E->getType()->isObjCRetainableType()) {
7164e5dd7070Spatrick
7165e5dd7070Spatrick bool ReturnsRetained;
7166e5dd7070Spatrick
7167e5dd7070Spatrick // For actual calls, we compute this by examining the type of the
7168e5dd7070Spatrick // called value.
7169e5dd7070Spatrick if (CallExpr *Call = dyn_cast<CallExpr>(E)) {
7170e5dd7070Spatrick Expr *Callee = Call->getCallee()->IgnoreParens();
7171e5dd7070Spatrick QualType T = Callee->getType();
7172e5dd7070Spatrick
7173e5dd7070Spatrick if (T == Context.BoundMemberTy) {
7174e5dd7070Spatrick // Handle pointer-to-members.
7175e5dd7070Spatrick if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Callee))
7176e5dd7070Spatrick T = BinOp->getRHS()->getType();
7177e5dd7070Spatrick else if (MemberExpr *Mem = dyn_cast<MemberExpr>(Callee))
7178e5dd7070Spatrick T = Mem->getMemberDecl()->getType();
7179e5dd7070Spatrick }
7180e5dd7070Spatrick
7181e5dd7070Spatrick if (const PointerType *Ptr = T->getAs<PointerType>())
7182e5dd7070Spatrick T = Ptr->getPointeeType();
7183e5dd7070Spatrick else if (const BlockPointerType *Ptr = T->getAs<BlockPointerType>())
7184e5dd7070Spatrick T = Ptr->getPointeeType();
7185e5dd7070Spatrick else if (const MemberPointerType *MemPtr = T->getAs<MemberPointerType>())
7186e5dd7070Spatrick T = MemPtr->getPointeeType();
7187e5dd7070Spatrick
7188ec727ea7Spatrick auto *FTy = T->castAs<FunctionType>();
7189e5dd7070Spatrick ReturnsRetained = FTy->getExtInfo().getProducesResult();
7190e5dd7070Spatrick
7191e5dd7070Spatrick // ActOnStmtExpr arranges things so that StmtExprs of retainable
7192e5dd7070Spatrick // type always produce a +1 object.
7193e5dd7070Spatrick } else if (isa<StmtExpr>(E)) {
7194e5dd7070Spatrick ReturnsRetained = true;
7195e5dd7070Spatrick
7196e5dd7070Spatrick // We hit this case with the lambda conversion-to-block optimization;
7197e5dd7070Spatrick // we don't want any extra casts here.
7198e5dd7070Spatrick } else if (isa<CastExpr>(E) &&
7199e5dd7070Spatrick isa<BlockExpr>(cast<CastExpr>(E)->getSubExpr())) {
7200e5dd7070Spatrick return E;
7201e5dd7070Spatrick
7202e5dd7070Spatrick // For message sends and property references, we try to find an
7203e5dd7070Spatrick // actual method. FIXME: we should infer retention by selector in
7204e5dd7070Spatrick // cases where we don't have an actual method.
7205e5dd7070Spatrick } else {
7206e5dd7070Spatrick ObjCMethodDecl *D = nullptr;
7207e5dd7070Spatrick if (ObjCMessageExpr *Send = dyn_cast<ObjCMessageExpr>(E)) {
7208e5dd7070Spatrick D = Send->getMethodDecl();
7209e5dd7070Spatrick } else if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(E)) {
7210e5dd7070Spatrick D = BoxedExpr->getBoxingMethod();
7211e5dd7070Spatrick } else if (ObjCArrayLiteral *ArrayLit = dyn_cast<ObjCArrayLiteral>(E)) {
7212e5dd7070Spatrick // Don't do reclaims if we're using the zero-element array
7213e5dd7070Spatrick // constant.
7214e5dd7070Spatrick if (ArrayLit->getNumElements() == 0 &&
7215e5dd7070Spatrick Context.getLangOpts().ObjCRuntime.hasEmptyCollections())
7216e5dd7070Spatrick return E;
7217e5dd7070Spatrick
7218e5dd7070Spatrick D = ArrayLit->getArrayWithObjectsMethod();
7219e5dd7070Spatrick } else if (ObjCDictionaryLiteral *DictLit
7220e5dd7070Spatrick = dyn_cast<ObjCDictionaryLiteral>(E)) {
7221e5dd7070Spatrick // Don't do reclaims if we're using the zero-element dictionary
7222e5dd7070Spatrick // constant.
7223e5dd7070Spatrick if (DictLit->getNumElements() == 0 &&
7224e5dd7070Spatrick Context.getLangOpts().ObjCRuntime.hasEmptyCollections())
7225e5dd7070Spatrick return E;
7226e5dd7070Spatrick
7227e5dd7070Spatrick D = DictLit->getDictWithObjectsMethod();
7228e5dd7070Spatrick }
7229e5dd7070Spatrick
7230e5dd7070Spatrick ReturnsRetained = (D && D->hasAttr<NSReturnsRetainedAttr>());
7231e5dd7070Spatrick
7232e5dd7070Spatrick // Don't do reclaims on performSelector calls; despite their
7233e5dd7070Spatrick // return type, the invoked method doesn't necessarily actually
7234e5dd7070Spatrick // return an object.
7235e5dd7070Spatrick if (!ReturnsRetained &&
7236e5dd7070Spatrick D && D->getMethodFamily() == OMF_performSelector)
7237e5dd7070Spatrick return E;
7238e5dd7070Spatrick }
7239e5dd7070Spatrick
7240e5dd7070Spatrick // Don't reclaim an object of Class type.
7241e5dd7070Spatrick if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType())
7242e5dd7070Spatrick return E;
7243e5dd7070Spatrick
7244e5dd7070Spatrick Cleanup.setExprNeedsCleanups(true);
7245e5dd7070Spatrick
7246e5dd7070Spatrick CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
7247e5dd7070Spatrick : CK_ARCReclaimReturnedObject);
7248e5dd7070Spatrick return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr,
7249a9ac8606Spatrick VK_PRValue, FPOptionsOverride());
7250e5dd7070Spatrick }
7251e5dd7070Spatrick
7252ec727ea7Spatrick if (E->getType().isDestructedType() == QualType::DK_nontrivial_c_struct)
7253ec727ea7Spatrick Cleanup.setExprNeedsCleanups(true);
7254ec727ea7Spatrick
7255e5dd7070Spatrick if (!getLangOpts().CPlusPlus)
7256e5dd7070Spatrick return E;
7257e5dd7070Spatrick
7258e5dd7070Spatrick // Search for the base element type (cf. ASTContext::getBaseElementType) with
7259e5dd7070Spatrick // a fast path for the common case that the type is directly a RecordType.
7260e5dd7070Spatrick const Type *T = Context.getCanonicalType(E->getType().getTypePtr());
7261e5dd7070Spatrick const RecordType *RT = nullptr;
7262e5dd7070Spatrick while (!RT) {
7263e5dd7070Spatrick switch (T->getTypeClass()) {
7264e5dd7070Spatrick case Type::Record:
7265e5dd7070Spatrick RT = cast<RecordType>(T);
7266e5dd7070Spatrick break;
7267e5dd7070Spatrick case Type::ConstantArray:
7268e5dd7070Spatrick case Type::IncompleteArray:
7269e5dd7070Spatrick case Type::VariableArray:
7270e5dd7070Spatrick case Type::DependentSizedArray:
7271e5dd7070Spatrick T = cast<ArrayType>(T)->getElementType().getTypePtr();
7272e5dd7070Spatrick break;
7273e5dd7070Spatrick default:
7274e5dd7070Spatrick return E;
7275e5dd7070Spatrick }
7276e5dd7070Spatrick }
7277e5dd7070Spatrick
7278e5dd7070Spatrick // That should be enough to guarantee that this type is complete, if we're
7279e5dd7070Spatrick // not processing a decltype expression.
7280e5dd7070Spatrick CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
7281e5dd7070Spatrick if (RD->isInvalidDecl() || RD->isDependentContext())
7282e5dd7070Spatrick return E;
7283e5dd7070Spatrick
7284e5dd7070Spatrick bool IsDecltype = ExprEvalContexts.back().ExprContext ==
7285e5dd7070Spatrick ExpressionEvaluationContextRecord::EK_Decltype;
7286e5dd7070Spatrick CXXDestructorDecl *Destructor = IsDecltype ? nullptr : LookupDestructor(RD);
7287e5dd7070Spatrick
7288e5dd7070Spatrick if (Destructor) {
7289e5dd7070Spatrick MarkFunctionReferenced(E->getExprLoc(), Destructor);
7290e5dd7070Spatrick CheckDestructorAccess(E->getExprLoc(), Destructor,
7291e5dd7070Spatrick PDiag(diag::err_access_dtor_temp)
7292e5dd7070Spatrick << E->getType());
7293e5dd7070Spatrick if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
7294e5dd7070Spatrick return ExprError();
7295e5dd7070Spatrick
7296e5dd7070Spatrick // If destructor is trivial, we can avoid the extra copy.
7297e5dd7070Spatrick if (Destructor->isTrivial())
7298e5dd7070Spatrick return E;
7299e5dd7070Spatrick
7300e5dd7070Spatrick // We need a cleanup, but we don't need to remember the temporary.
7301e5dd7070Spatrick Cleanup.setExprNeedsCleanups(true);
7302e5dd7070Spatrick }
7303e5dd7070Spatrick
7304e5dd7070Spatrick CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor);
7305e5dd7070Spatrick CXXBindTemporaryExpr *Bind = CXXBindTemporaryExpr::Create(Context, Temp, E);
7306e5dd7070Spatrick
7307e5dd7070Spatrick if (IsDecltype)
7308e5dd7070Spatrick ExprEvalContexts.back().DelayedDecltypeBinds.push_back(Bind);
7309e5dd7070Spatrick
7310e5dd7070Spatrick return Bind;
7311e5dd7070Spatrick }
7312e5dd7070Spatrick
7313e5dd7070Spatrick ExprResult
MaybeCreateExprWithCleanups(ExprResult SubExpr)7314e5dd7070Spatrick Sema::MaybeCreateExprWithCleanups(ExprResult SubExpr) {
7315e5dd7070Spatrick if (SubExpr.isInvalid())
7316e5dd7070Spatrick return ExprError();
7317e5dd7070Spatrick
7318e5dd7070Spatrick return MaybeCreateExprWithCleanups(SubExpr.get());
7319e5dd7070Spatrick }
7320e5dd7070Spatrick
MaybeCreateExprWithCleanups(Expr * SubExpr)7321e5dd7070Spatrick Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) {
7322e5dd7070Spatrick assert(SubExpr && "subexpression can't be null!");
7323e5dd7070Spatrick
7324e5dd7070Spatrick CleanupVarDeclMarking();
7325e5dd7070Spatrick
7326e5dd7070Spatrick unsigned FirstCleanup = ExprEvalContexts.back().NumCleanupObjects;
7327e5dd7070Spatrick assert(ExprCleanupObjects.size() >= FirstCleanup);
7328e5dd7070Spatrick assert(Cleanup.exprNeedsCleanups() ||
7329e5dd7070Spatrick ExprCleanupObjects.size() == FirstCleanup);
7330e5dd7070Spatrick if (!Cleanup.exprNeedsCleanups())
7331e5dd7070Spatrick return SubExpr;
7332e5dd7070Spatrick
7333*12c85518Srobert auto Cleanups = llvm::ArrayRef(ExprCleanupObjects.begin() + FirstCleanup,
7334e5dd7070Spatrick ExprCleanupObjects.size() - FirstCleanup);
7335e5dd7070Spatrick
7336e5dd7070Spatrick auto *E = ExprWithCleanups::Create(
7337e5dd7070Spatrick Context, SubExpr, Cleanup.cleanupsHaveSideEffects(), Cleanups);
7338e5dd7070Spatrick DiscardCleanupsInEvaluationContext();
7339e5dd7070Spatrick
7340e5dd7070Spatrick return E;
7341e5dd7070Spatrick }
7342e5dd7070Spatrick
MaybeCreateStmtWithCleanups(Stmt * SubStmt)7343e5dd7070Spatrick Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) {
7344e5dd7070Spatrick assert(SubStmt && "sub-statement can't be null!");
7345e5dd7070Spatrick
7346e5dd7070Spatrick CleanupVarDeclMarking();
7347e5dd7070Spatrick
7348e5dd7070Spatrick if (!Cleanup.exprNeedsCleanups())
7349e5dd7070Spatrick return SubStmt;
7350e5dd7070Spatrick
7351e5dd7070Spatrick // FIXME: In order to attach the temporaries, wrap the statement into
7352e5dd7070Spatrick // a StmtExpr; currently this is only used for asm statements.
7353e5dd7070Spatrick // This is hacky, either create a new CXXStmtWithTemporaries statement or
7354e5dd7070Spatrick // a new AsmStmtWithTemporaries.
7355*12c85518Srobert CompoundStmt *CompStmt =
7356*12c85518Srobert CompoundStmt::Create(Context, SubStmt, FPOptionsOverride(),
7357*12c85518Srobert SourceLocation(), SourceLocation());
7358e5dd7070Spatrick Expr *E = new (Context)
7359e5dd7070Spatrick StmtExpr(CompStmt, Context.VoidTy, SourceLocation(), SourceLocation(),
7360e5dd7070Spatrick /*FIXME TemplateDepth=*/0);
7361e5dd7070Spatrick return MaybeCreateExprWithCleanups(E);
7362e5dd7070Spatrick }
7363e5dd7070Spatrick
7364e5dd7070Spatrick /// Process the expression contained within a decltype. For such expressions,
7365e5dd7070Spatrick /// certain semantic checks on temporaries are delayed until this point, and
7366e5dd7070Spatrick /// are omitted for the 'topmost' call in the decltype expression. If the
7367e5dd7070Spatrick /// topmost call bound a temporary, strip that temporary off the expression.
ActOnDecltypeExpression(Expr * E)7368e5dd7070Spatrick ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
7369e5dd7070Spatrick assert(ExprEvalContexts.back().ExprContext ==
7370e5dd7070Spatrick ExpressionEvaluationContextRecord::EK_Decltype &&
7371e5dd7070Spatrick "not in a decltype expression");
7372e5dd7070Spatrick
7373e5dd7070Spatrick ExprResult Result = CheckPlaceholderExpr(E);
7374e5dd7070Spatrick if (Result.isInvalid())
7375e5dd7070Spatrick return ExprError();
7376e5dd7070Spatrick E = Result.get();
7377e5dd7070Spatrick
7378e5dd7070Spatrick // C++11 [expr.call]p11:
7379e5dd7070Spatrick // If a function call is a prvalue of object type,
7380e5dd7070Spatrick // -- if the function call is either
7381e5dd7070Spatrick // -- the operand of a decltype-specifier, or
7382e5dd7070Spatrick // -- the right operand of a comma operator that is the operand of a
7383e5dd7070Spatrick // decltype-specifier,
7384e5dd7070Spatrick // a temporary object is not introduced for the prvalue.
7385e5dd7070Spatrick
7386e5dd7070Spatrick // Recursively rebuild ParenExprs and comma expressions to strip out the
7387e5dd7070Spatrick // outermost CXXBindTemporaryExpr, if any.
7388e5dd7070Spatrick if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
7389e5dd7070Spatrick ExprResult SubExpr = ActOnDecltypeExpression(PE->getSubExpr());
7390e5dd7070Spatrick if (SubExpr.isInvalid())
7391e5dd7070Spatrick return ExprError();
7392e5dd7070Spatrick if (SubExpr.get() == PE->getSubExpr())
7393e5dd7070Spatrick return E;
7394e5dd7070Spatrick return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.get());
7395e5dd7070Spatrick }
7396e5dd7070Spatrick if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
7397e5dd7070Spatrick if (BO->getOpcode() == BO_Comma) {
7398e5dd7070Spatrick ExprResult RHS = ActOnDecltypeExpression(BO->getRHS());
7399e5dd7070Spatrick if (RHS.isInvalid())
7400e5dd7070Spatrick return ExprError();
7401e5dd7070Spatrick if (RHS.get() == BO->getRHS())
7402e5dd7070Spatrick return E;
7403ec727ea7Spatrick return BinaryOperator::Create(Context, BO->getLHS(), RHS.get(), BO_Comma,
7404ec727ea7Spatrick BO->getType(), BO->getValueKind(),
7405ec727ea7Spatrick BO->getObjectKind(), BO->getOperatorLoc(),
7406*12c85518Srobert BO->getFPFeatures());
7407e5dd7070Spatrick }
7408e5dd7070Spatrick }
7409e5dd7070Spatrick
7410e5dd7070Spatrick CXXBindTemporaryExpr *TopBind = dyn_cast<CXXBindTemporaryExpr>(E);
7411e5dd7070Spatrick CallExpr *TopCall = TopBind ? dyn_cast<CallExpr>(TopBind->getSubExpr())
7412e5dd7070Spatrick : nullptr;
7413e5dd7070Spatrick if (TopCall)
7414e5dd7070Spatrick E = TopCall;
7415e5dd7070Spatrick else
7416e5dd7070Spatrick TopBind = nullptr;
7417e5dd7070Spatrick
7418e5dd7070Spatrick // Disable the special decltype handling now.
7419e5dd7070Spatrick ExprEvalContexts.back().ExprContext =
7420e5dd7070Spatrick ExpressionEvaluationContextRecord::EK_Other;
7421e5dd7070Spatrick
7422e5dd7070Spatrick Result = CheckUnevaluatedOperand(E);
7423e5dd7070Spatrick if (Result.isInvalid())
7424e5dd7070Spatrick return ExprError();
7425e5dd7070Spatrick E = Result.get();
7426e5dd7070Spatrick
7427e5dd7070Spatrick // In MS mode, don't perform any extra checking of call return types within a
7428e5dd7070Spatrick // decltype expression.
7429e5dd7070Spatrick if (getLangOpts().MSVCCompat)
7430e5dd7070Spatrick return E;
7431e5dd7070Spatrick
7432e5dd7070Spatrick // Perform the semantic checks we delayed until this point.
7433e5dd7070Spatrick for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeCalls.size();
7434e5dd7070Spatrick I != N; ++I) {
7435e5dd7070Spatrick CallExpr *Call = ExprEvalContexts.back().DelayedDecltypeCalls[I];
7436e5dd7070Spatrick if (Call == TopCall)
7437e5dd7070Spatrick continue;
7438e5dd7070Spatrick
7439e5dd7070Spatrick if (CheckCallReturnType(Call->getCallReturnType(Context),
7440e5dd7070Spatrick Call->getBeginLoc(), Call, Call->getDirectCallee()))
7441e5dd7070Spatrick return ExprError();
7442e5dd7070Spatrick }
7443e5dd7070Spatrick
7444e5dd7070Spatrick // Now all relevant types are complete, check the destructors are accessible
7445e5dd7070Spatrick // and non-deleted, and annotate them on the temporaries.
7446e5dd7070Spatrick for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeBinds.size();
7447e5dd7070Spatrick I != N; ++I) {
7448e5dd7070Spatrick CXXBindTemporaryExpr *Bind =
7449e5dd7070Spatrick ExprEvalContexts.back().DelayedDecltypeBinds[I];
7450e5dd7070Spatrick if (Bind == TopBind)
7451e5dd7070Spatrick continue;
7452e5dd7070Spatrick
7453e5dd7070Spatrick CXXTemporary *Temp = Bind->getTemporary();
7454e5dd7070Spatrick
7455e5dd7070Spatrick CXXRecordDecl *RD =
7456e5dd7070Spatrick Bind->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
7457e5dd7070Spatrick CXXDestructorDecl *Destructor = LookupDestructor(RD);
7458e5dd7070Spatrick Temp->setDestructor(Destructor);
7459e5dd7070Spatrick
7460e5dd7070Spatrick MarkFunctionReferenced(Bind->getExprLoc(), Destructor);
7461e5dd7070Spatrick CheckDestructorAccess(Bind->getExprLoc(), Destructor,
7462e5dd7070Spatrick PDiag(diag::err_access_dtor_temp)
7463e5dd7070Spatrick << Bind->getType());
7464e5dd7070Spatrick if (DiagnoseUseOfDecl(Destructor, Bind->getExprLoc()))
7465e5dd7070Spatrick return ExprError();
7466e5dd7070Spatrick
7467e5dd7070Spatrick // We need a cleanup, but we don't need to remember the temporary.
7468e5dd7070Spatrick Cleanup.setExprNeedsCleanups(true);
7469e5dd7070Spatrick }
7470e5dd7070Spatrick
7471e5dd7070Spatrick // Possibly strip off the top CXXBindTemporaryExpr.
7472e5dd7070Spatrick return E;
7473e5dd7070Spatrick }
7474e5dd7070Spatrick
7475e5dd7070Spatrick /// Note a set of 'operator->' functions that were used for a member access.
noteOperatorArrows(Sema & S,ArrayRef<FunctionDecl * > OperatorArrows)7476e5dd7070Spatrick static void noteOperatorArrows(Sema &S,
7477e5dd7070Spatrick ArrayRef<FunctionDecl *> OperatorArrows) {
7478e5dd7070Spatrick unsigned SkipStart = OperatorArrows.size(), SkipCount = 0;
7479e5dd7070Spatrick // FIXME: Make this configurable?
7480e5dd7070Spatrick unsigned Limit = 9;
7481e5dd7070Spatrick if (OperatorArrows.size() > Limit) {
7482e5dd7070Spatrick // Produce Limit-1 normal notes and one 'skipping' note.
7483e5dd7070Spatrick SkipStart = (Limit - 1) / 2 + (Limit - 1) % 2;
7484e5dd7070Spatrick SkipCount = OperatorArrows.size() - (Limit - 1);
7485e5dd7070Spatrick }
7486e5dd7070Spatrick
7487e5dd7070Spatrick for (unsigned I = 0; I < OperatorArrows.size(); /**/) {
7488e5dd7070Spatrick if (I == SkipStart) {
7489e5dd7070Spatrick S.Diag(OperatorArrows[I]->getLocation(),
7490e5dd7070Spatrick diag::note_operator_arrows_suppressed)
7491e5dd7070Spatrick << SkipCount;
7492e5dd7070Spatrick I += SkipCount;
7493e5dd7070Spatrick } else {
7494e5dd7070Spatrick S.Diag(OperatorArrows[I]->getLocation(), diag::note_operator_arrow_here)
7495e5dd7070Spatrick << OperatorArrows[I]->getCallResultType();
7496e5dd7070Spatrick ++I;
7497e5dd7070Spatrick }
7498e5dd7070Spatrick }
7499e5dd7070Spatrick }
7500e5dd7070Spatrick
ActOnStartCXXMemberReference(Scope * S,Expr * Base,SourceLocation OpLoc,tok::TokenKind OpKind,ParsedType & ObjectType,bool & MayBePseudoDestructor)7501e5dd7070Spatrick ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
7502e5dd7070Spatrick SourceLocation OpLoc,
7503e5dd7070Spatrick tok::TokenKind OpKind,
7504e5dd7070Spatrick ParsedType &ObjectType,
7505e5dd7070Spatrick bool &MayBePseudoDestructor) {
7506e5dd7070Spatrick // Since this might be a postfix expression, get rid of ParenListExprs.
7507e5dd7070Spatrick ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
7508e5dd7070Spatrick if (Result.isInvalid()) return ExprError();
7509e5dd7070Spatrick Base = Result.get();
7510e5dd7070Spatrick
7511e5dd7070Spatrick Result = CheckPlaceholderExpr(Base);
7512e5dd7070Spatrick if (Result.isInvalid()) return ExprError();
7513e5dd7070Spatrick Base = Result.get();
7514e5dd7070Spatrick
7515e5dd7070Spatrick QualType BaseType = Base->getType();
7516e5dd7070Spatrick MayBePseudoDestructor = false;
7517e5dd7070Spatrick if (BaseType->isDependentType()) {
7518e5dd7070Spatrick // If we have a pointer to a dependent type and are using the -> operator,
7519e5dd7070Spatrick // the object type is the type that the pointer points to. We might still
7520e5dd7070Spatrick // have enough information about that type to do something useful.
7521e5dd7070Spatrick if (OpKind == tok::arrow)
7522e5dd7070Spatrick if (const PointerType *Ptr = BaseType->getAs<PointerType>())
7523e5dd7070Spatrick BaseType = Ptr->getPointeeType();
7524e5dd7070Spatrick
7525e5dd7070Spatrick ObjectType = ParsedType::make(BaseType);
7526e5dd7070Spatrick MayBePseudoDestructor = true;
7527e5dd7070Spatrick return Base;
7528e5dd7070Spatrick }
7529e5dd7070Spatrick
7530e5dd7070Spatrick // C++ [over.match.oper]p8:
7531e5dd7070Spatrick // [...] When operator->returns, the operator-> is applied to the value
7532e5dd7070Spatrick // returned, with the original second operand.
7533e5dd7070Spatrick if (OpKind == tok::arrow) {
7534e5dd7070Spatrick QualType StartingType = BaseType;
7535e5dd7070Spatrick bool NoArrowOperatorFound = false;
7536e5dd7070Spatrick bool FirstIteration = true;
7537e5dd7070Spatrick FunctionDecl *CurFD = dyn_cast<FunctionDecl>(CurContext);
7538e5dd7070Spatrick // The set of types we've considered so far.
7539e5dd7070Spatrick llvm::SmallPtrSet<CanQualType,8> CTypes;
7540e5dd7070Spatrick SmallVector<FunctionDecl*, 8> OperatorArrows;
7541e5dd7070Spatrick CTypes.insert(Context.getCanonicalType(BaseType));
7542e5dd7070Spatrick
7543e5dd7070Spatrick while (BaseType->isRecordType()) {
7544e5dd7070Spatrick if (OperatorArrows.size() >= getLangOpts().ArrowDepth) {
7545e5dd7070Spatrick Diag(OpLoc, diag::err_operator_arrow_depth_exceeded)
7546e5dd7070Spatrick << StartingType << getLangOpts().ArrowDepth << Base->getSourceRange();
7547e5dd7070Spatrick noteOperatorArrows(*this, OperatorArrows);
7548e5dd7070Spatrick Diag(OpLoc, diag::note_operator_arrow_depth)
7549e5dd7070Spatrick << getLangOpts().ArrowDepth;
7550e5dd7070Spatrick return ExprError();
7551e5dd7070Spatrick }
7552e5dd7070Spatrick
7553e5dd7070Spatrick Result = BuildOverloadedArrowExpr(
7554e5dd7070Spatrick S, Base, OpLoc,
7555e5dd7070Spatrick // When in a template specialization and on the first loop iteration,
7556e5dd7070Spatrick // potentially give the default diagnostic (with the fixit in a
7557e5dd7070Spatrick // separate note) instead of having the error reported back to here
7558e5dd7070Spatrick // and giving a diagnostic with a fixit attached to the error itself.
7559e5dd7070Spatrick (FirstIteration && CurFD && CurFD->isFunctionTemplateSpecialization())
7560e5dd7070Spatrick ? nullptr
7561e5dd7070Spatrick : &NoArrowOperatorFound);
7562e5dd7070Spatrick if (Result.isInvalid()) {
7563e5dd7070Spatrick if (NoArrowOperatorFound) {
7564e5dd7070Spatrick if (FirstIteration) {
7565e5dd7070Spatrick Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
7566e5dd7070Spatrick << BaseType << 1 << Base->getSourceRange()
7567e5dd7070Spatrick << FixItHint::CreateReplacement(OpLoc, ".");
7568e5dd7070Spatrick OpKind = tok::period;
7569e5dd7070Spatrick break;
7570e5dd7070Spatrick }
7571e5dd7070Spatrick Diag(OpLoc, diag::err_typecheck_member_reference_arrow)
7572e5dd7070Spatrick << BaseType << Base->getSourceRange();
7573e5dd7070Spatrick CallExpr *CE = dyn_cast<CallExpr>(Base);
7574e5dd7070Spatrick if (Decl *CD = (CE ? CE->getCalleeDecl() : nullptr)) {
7575e5dd7070Spatrick Diag(CD->getBeginLoc(),
7576e5dd7070Spatrick diag::note_member_reference_arrow_from_operator_arrow);
7577e5dd7070Spatrick }
7578e5dd7070Spatrick }
7579e5dd7070Spatrick return ExprError();
7580e5dd7070Spatrick }
7581e5dd7070Spatrick Base = Result.get();
7582e5dd7070Spatrick if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(Base))
7583e5dd7070Spatrick OperatorArrows.push_back(OpCall->getDirectCallee());
7584e5dd7070Spatrick BaseType = Base->getType();
7585e5dd7070Spatrick CanQualType CBaseType = Context.getCanonicalType(BaseType);
7586e5dd7070Spatrick if (!CTypes.insert(CBaseType).second) {
7587e5dd7070Spatrick Diag(OpLoc, diag::err_operator_arrow_circular) << StartingType;
7588e5dd7070Spatrick noteOperatorArrows(*this, OperatorArrows);
7589e5dd7070Spatrick return ExprError();
7590e5dd7070Spatrick }
7591e5dd7070Spatrick FirstIteration = false;
7592e5dd7070Spatrick }
7593e5dd7070Spatrick
7594e5dd7070Spatrick if (OpKind == tok::arrow) {
7595e5dd7070Spatrick if (BaseType->isPointerType())
7596e5dd7070Spatrick BaseType = BaseType->getPointeeType();
7597e5dd7070Spatrick else if (auto *AT = Context.getAsArrayType(BaseType))
7598e5dd7070Spatrick BaseType = AT->getElementType();
7599e5dd7070Spatrick }
7600e5dd7070Spatrick }
7601e5dd7070Spatrick
7602e5dd7070Spatrick // Objective-C properties allow "." access on Objective-C pointer types,
7603e5dd7070Spatrick // so adjust the base type to the object type itself.
7604e5dd7070Spatrick if (BaseType->isObjCObjectPointerType())
7605e5dd7070Spatrick BaseType = BaseType->getPointeeType();
7606e5dd7070Spatrick
7607e5dd7070Spatrick // C++ [basic.lookup.classref]p2:
7608e5dd7070Spatrick // [...] If the type of the object expression is of pointer to scalar
7609e5dd7070Spatrick // type, the unqualified-id is looked up in the context of the complete
7610e5dd7070Spatrick // postfix-expression.
7611e5dd7070Spatrick //
7612e5dd7070Spatrick // This also indicates that we could be parsing a pseudo-destructor-name.
7613e5dd7070Spatrick // Note that Objective-C class and object types can be pseudo-destructor
7614e5dd7070Spatrick // expressions or normal member (ivar or property) access expressions, and
7615e5dd7070Spatrick // it's legal for the type to be incomplete if this is a pseudo-destructor
7616e5dd7070Spatrick // call. We'll do more incomplete-type checks later in the lookup process,
7617e5dd7070Spatrick // so just skip this check for ObjC types.
7618e5dd7070Spatrick if (!BaseType->isRecordType()) {
7619e5dd7070Spatrick ObjectType = ParsedType::make(BaseType);
7620e5dd7070Spatrick MayBePseudoDestructor = true;
7621e5dd7070Spatrick return Base;
7622e5dd7070Spatrick }
7623e5dd7070Spatrick
7624e5dd7070Spatrick // The object type must be complete (or dependent), or
7625e5dd7070Spatrick // C++11 [expr.prim.general]p3:
7626e5dd7070Spatrick // Unlike the object expression in other contexts, *this is not required to
7627e5dd7070Spatrick // be of complete type for purposes of class member access (5.2.5) outside
7628e5dd7070Spatrick // the member function body.
7629e5dd7070Spatrick if (!BaseType->isDependentType() &&
7630e5dd7070Spatrick !isThisOutsideMemberFunctionBody(BaseType) &&
7631*12c85518Srobert RequireCompleteType(OpLoc, BaseType,
7632*12c85518Srobert diag::err_incomplete_member_access)) {
7633*12c85518Srobert return CreateRecoveryExpr(Base->getBeginLoc(), Base->getEndLoc(), {Base});
7634*12c85518Srobert }
7635e5dd7070Spatrick
7636e5dd7070Spatrick // C++ [basic.lookup.classref]p2:
7637e5dd7070Spatrick // If the id-expression in a class member access (5.2.5) is an
7638e5dd7070Spatrick // unqualified-id, and the type of the object expression is of a class
7639e5dd7070Spatrick // type C (or of pointer to a class type C), the unqualified-id is looked
7640e5dd7070Spatrick // up in the scope of class C. [...]
7641e5dd7070Spatrick ObjectType = ParsedType::make(BaseType);
7642e5dd7070Spatrick return Base;
7643e5dd7070Spatrick }
7644e5dd7070Spatrick
CheckArrow(Sema & S,QualType & ObjectType,Expr * & Base,tok::TokenKind & OpKind,SourceLocation OpLoc)7645e5dd7070Spatrick static bool CheckArrow(Sema &S, QualType &ObjectType, Expr *&Base,
7646e5dd7070Spatrick tok::TokenKind &OpKind, SourceLocation OpLoc) {
7647e5dd7070Spatrick if (Base->hasPlaceholderType()) {
7648e5dd7070Spatrick ExprResult result = S.CheckPlaceholderExpr(Base);
7649e5dd7070Spatrick if (result.isInvalid()) return true;
7650e5dd7070Spatrick Base = result.get();
7651e5dd7070Spatrick }
7652e5dd7070Spatrick ObjectType = Base->getType();
7653e5dd7070Spatrick
7654e5dd7070Spatrick // C++ [expr.pseudo]p2:
7655e5dd7070Spatrick // The left-hand side of the dot operator shall be of scalar type. The
7656e5dd7070Spatrick // left-hand side of the arrow operator shall be of pointer to scalar type.
7657e5dd7070Spatrick // This scalar type is the object type.
7658e5dd7070Spatrick // Note that this is rather different from the normal handling for the
7659e5dd7070Spatrick // arrow operator.
7660e5dd7070Spatrick if (OpKind == tok::arrow) {
7661a9ac8606Spatrick // The operator requires a prvalue, so perform lvalue conversions.
7662a9ac8606Spatrick // Only do this if we might plausibly end with a pointer, as otherwise
7663a9ac8606Spatrick // this was likely to be intended to be a '.'.
7664a9ac8606Spatrick if (ObjectType->isPointerType() || ObjectType->isArrayType() ||
7665a9ac8606Spatrick ObjectType->isFunctionType()) {
7666a9ac8606Spatrick ExprResult BaseResult = S.DefaultFunctionArrayLvalueConversion(Base);
7667a9ac8606Spatrick if (BaseResult.isInvalid())
7668a9ac8606Spatrick return true;
7669a9ac8606Spatrick Base = BaseResult.get();
7670a9ac8606Spatrick ObjectType = Base->getType();
7671a9ac8606Spatrick }
7672a9ac8606Spatrick
7673e5dd7070Spatrick if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
7674e5dd7070Spatrick ObjectType = Ptr->getPointeeType();
7675e5dd7070Spatrick } else if (!Base->isTypeDependent()) {
7676e5dd7070Spatrick // The user wrote "p->" when they probably meant "p."; fix it.
7677e5dd7070Spatrick S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
7678e5dd7070Spatrick << ObjectType << true
7679e5dd7070Spatrick << FixItHint::CreateReplacement(OpLoc, ".");
7680e5dd7070Spatrick if (S.isSFINAEContext())
7681e5dd7070Spatrick return true;
7682e5dd7070Spatrick
7683e5dd7070Spatrick OpKind = tok::period;
7684e5dd7070Spatrick }
7685e5dd7070Spatrick }
7686e5dd7070Spatrick
7687e5dd7070Spatrick return false;
7688e5dd7070Spatrick }
7689e5dd7070Spatrick
7690e5dd7070Spatrick /// Check if it's ok to try and recover dot pseudo destructor calls on
7691e5dd7070Spatrick /// pointer objects.
7692e5dd7070Spatrick static bool
canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema & SemaRef,QualType DestructedType)7693e5dd7070Spatrick canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema &SemaRef,
7694e5dd7070Spatrick QualType DestructedType) {
7695e5dd7070Spatrick // If this is a record type, check if its destructor is callable.
7696e5dd7070Spatrick if (auto *RD = DestructedType->getAsCXXRecordDecl()) {
7697e5dd7070Spatrick if (RD->hasDefinition())
7698e5dd7070Spatrick if (CXXDestructorDecl *D = SemaRef.LookupDestructor(RD))
7699e5dd7070Spatrick return SemaRef.CanUseDecl(D, /*TreatUnavailableAsInvalid=*/false);
7700e5dd7070Spatrick return false;
7701e5dd7070Spatrick }
7702e5dd7070Spatrick
7703e5dd7070Spatrick // Otherwise, check if it's a type for which it's valid to use a pseudo-dtor.
7704e5dd7070Spatrick return DestructedType->isDependentType() || DestructedType->isScalarType() ||
7705e5dd7070Spatrick DestructedType->isVectorType();
7706e5dd7070Spatrick }
7707e5dd7070Spatrick
BuildPseudoDestructorExpr(Expr * Base,SourceLocation OpLoc,tok::TokenKind OpKind,const CXXScopeSpec & SS,TypeSourceInfo * ScopeTypeInfo,SourceLocation CCLoc,SourceLocation TildeLoc,PseudoDestructorTypeStorage Destructed)7708e5dd7070Spatrick ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
7709e5dd7070Spatrick SourceLocation OpLoc,
7710e5dd7070Spatrick tok::TokenKind OpKind,
7711e5dd7070Spatrick const CXXScopeSpec &SS,
7712e5dd7070Spatrick TypeSourceInfo *ScopeTypeInfo,
7713e5dd7070Spatrick SourceLocation CCLoc,
7714e5dd7070Spatrick SourceLocation TildeLoc,
7715e5dd7070Spatrick PseudoDestructorTypeStorage Destructed) {
7716e5dd7070Spatrick TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo();
7717e5dd7070Spatrick
7718e5dd7070Spatrick QualType ObjectType;
7719e5dd7070Spatrick if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
7720e5dd7070Spatrick return ExprError();
7721e5dd7070Spatrick
7722e5dd7070Spatrick if (!ObjectType->isDependentType() && !ObjectType->isScalarType() &&
7723e5dd7070Spatrick !ObjectType->isVectorType()) {
7724e5dd7070Spatrick if (getLangOpts().MSVCCompat && ObjectType->isVoidType())
7725e5dd7070Spatrick Diag(OpLoc, diag::ext_pseudo_dtor_on_void) << Base->getSourceRange();
7726e5dd7070Spatrick else {
7727e5dd7070Spatrick Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
7728e5dd7070Spatrick << ObjectType << Base->getSourceRange();
7729e5dd7070Spatrick return ExprError();
7730e5dd7070Spatrick }
7731e5dd7070Spatrick }
7732e5dd7070Spatrick
7733e5dd7070Spatrick // C++ [expr.pseudo]p2:
7734e5dd7070Spatrick // [...] The cv-unqualified versions of the object type and of the type
7735e5dd7070Spatrick // designated by the pseudo-destructor-name shall be the same type.
7736e5dd7070Spatrick if (DestructedTypeInfo) {
7737e5dd7070Spatrick QualType DestructedType = DestructedTypeInfo->getType();
7738*12c85518Srobert SourceLocation DestructedTypeStart =
7739*12c85518Srobert DestructedTypeInfo->getTypeLoc().getBeginLoc();
7740e5dd7070Spatrick if (!DestructedType->isDependentType() && !ObjectType->isDependentType()) {
7741e5dd7070Spatrick if (!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
7742e5dd7070Spatrick // Detect dot pseudo destructor calls on pointer objects, e.g.:
7743e5dd7070Spatrick // Foo *foo;
7744e5dd7070Spatrick // foo.~Foo();
7745e5dd7070Spatrick if (OpKind == tok::period && ObjectType->isPointerType() &&
7746e5dd7070Spatrick Context.hasSameUnqualifiedType(DestructedType,
7747e5dd7070Spatrick ObjectType->getPointeeType())) {
7748e5dd7070Spatrick auto Diagnostic =
7749e5dd7070Spatrick Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
7750e5dd7070Spatrick << ObjectType << /*IsArrow=*/0 << Base->getSourceRange();
7751e5dd7070Spatrick
7752e5dd7070Spatrick // Issue a fixit only when the destructor is valid.
7753e5dd7070Spatrick if (canRecoverDotPseudoDestructorCallsOnPointerObjects(
7754e5dd7070Spatrick *this, DestructedType))
7755e5dd7070Spatrick Diagnostic << FixItHint::CreateReplacement(OpLoc, "->");
7756e5dd7070Spatrick
7757e5dd7070Spatrick // Recover by setting the object type to the destructed type and the
7758e5dd7070Spatrick // operator to '->'.
7759e5dd7070Spatrick ObjectType = DestructedType;
7760e5dd7070Spatrick OpKind = tok::arrow;
7761e5dd7070Spatrick } else {
7762e5dd7070Spatrick Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
7763e5dd7070Spatrick << ObjectType << DestructedType << Base->getSourceRange()
7764*12c85518Srobert << DestructedTypeInfo->getTypeLoc().getSourceRange();
7765e5dd7070Spatrick
7766e5dd7070Spatrick // Recover by setting the destructed type to the object type.
7767e5dd7070Spatrick DestructedType = ObjectType;
7768e5dd7070Spatrick DestructedTypeInfo =
7769e5dd7070Spatrick Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart);
7770e5dd7070Spatrick Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
7771e5dd7070Spatrick }
7772e5dd7070Spatrick } else if (DestructedType.getObjCLifetime() !=
7773e5dd7070Spatrick ObjectType.getObjCLifetime()) {
7774e5dd7070Spatrick
7775e5dd7070Spatrick if (DestructedType.getObjCLifetime() == Qualifiers::OCL_None) {
7776e5dd7070Spatrick // Okay: just pretend that the user provided the correctly-qualified
7777e5dd7070Spatrick // type.
7778e5dd7070Spatrick } else {
7779e5dd7070Spatrick Diag(DestructedTypeStart, diag::err_arc_pseudo_dtor_inconstant_quals)
7780e5dd7070Spatrick << ObjectType << DestructedType << Base->getSourceRange()
7781*12c85518Srobert << DestructedTypeInfo->getTypeLoc().getSourceRange();
7782e5dd7070Spatrick }
7783e5dd7070Spatrick
7784e5dd7070Spatrick // Recover by setting the destructed type to the object type.
7785e5dd7070Spatrick DestructedType = ObjectType;
7786e5dd7070Spatrick DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType,
7787e5dd7070Spatrick DestructedTypeStart);
7788e5dd7070Spatrick Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
7789e5dd7070Spatrick }
7790e5dd7070Spatrick }
7791e5dd7070Spatrick }
7792e5dd7070Spatrick
7793e5dd7070Spatrick // C++ [expr.pseudo]p2:
7794e5dd7070Spatrick // [...] Furthermore, the two type-names in a pseudo-destructor-name of the
7795e5dd7070Spatrick // form
7796e5dd7070Spatrick //
7797e5dd7070Spatrick // ::[opt] nested-name-specifier[opt] type-name :: ~ type-name
7798e5dd7070Spatrick //
7799e5dd7070Spatrick // shall designate the same scalar type.
7800e5dd7070Spatrick if (ScopeTypeInfo) {
7801e5dd7070Spatrick QualType ScopeType = ScopeTypeInfo->getType();
7802e5dd7070Spatrick if (!ScopeType->isDependentType() && !ObjectType->isDependentType() &&
7803e5dd7070Spatrick !Context.hasSameUnqualifiedType(ScopeType, ObjectType)) {
7804e5dd7070Spatrick
7805*12c85518Srobert Diag(ScopeTypeInfo->getTypeLoc().getSourceRange().getBegin(),
7806e5dd7070Spatrick diag::err_pseudo_dtor_type_mismatch)
7807e5dd7070Spatrick << ObjectType << ScopeType << Base->getSourceRange()
7808*12c85518Srobert << ScopeTypeInfo->getTypeLoc().getSourceRange();
7809e5dd7070Spatrick
7810e5dd7070Spatrick ScopeType = QualType();
7811e5dd7070Spatrick ScopeTypeInfo = nullptr;
7812e5dd7070Spatrick }
7813e5dd7070Spatrick }
7814e5dd7070Spatrick
7815e5dd7070Spatrick Expr *Result
7816e5dd7070Spatrick = new (Context) CXXPseudoDestructorExpr(Context, Base,
7817e5dd7070Spatrick OpKind == tok::arrow, OpLoc,
7818e5dd7070Spatrick SS.getWithLocInContext(Context),
7819e5dd7070Spatrick ScopeTypeInfo,
7820e5dd7070Spatrick CCLoc,
7821e5dd7070Spatrick TildeLoc,
7822e5dd7070Spatrick Destructed);
7823e5dd7070Spatrick
7824e5dd7070Spatrick return Result;
7825e5dd7070Spatrick }
7826e5dd7070Spatrick
ActOnPseudoDestructorExpr(Scope * S,Expr * Base,SourceLocation OpLoc,tok::TokenKind OpKind,CXXScopeSpec & SS,UnqualifiedId & FirstTypeName,SourceLocation CCLoc,SourceLocation TildeLoc,UnqualifiedId & SecondTypeName)7827e5dd7070Spatrick ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
7828e5dd7070Spatrick SourceLocation OpLoc,
7829e5dd7070Spatrick tok::TokenKind OpKind,
7830e5dd7070Spatrick CXXScopeSpec &SS,
7831e5dd7070Spatrick UnqualifiedId &FirstTypeName,
7832e5dd7070Spatrick SourceLocation CCLoc,
7833e5dd7070Spatrick SourceLocation TildeLoc,
7834e5dd7070Spatrick UnqualifiedId &SecondTypeName) {
7835e5dd7070Spatrick assert((FirstTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId ||
7836e5dd7070Spatrick FirstTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) &&
7837e5dd7070Spatrick "Invalid first type name in pseudo-destructor");
7838e5dd7070Spatrick assert((SecondTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId ||
7839e5dd7070Spatrick SecondTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) &&
7840e5dd7070Spatrick "Invalid second type name in pseudo-destructor");
7841e5dd7070Spatrick
7842e5dd7070Spatrick QualType ObjectType;
7843e5dd7070Spatrick if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
7844e5dd7070Spatrick return ExprError();
7845e5dd7070Spatrick
7846e5dd7070Spatrick // Compute the object type that we should use for name lookup purposes. Only
7847e5dd7070Spatrick // record types and dependent types matter.
7848e5dd7070Spatrick ParsedType ObjectTypePtrForLookup;
7849e5dd7070Spatrick if (!SS.isSet()) {
7850e5dd7070Spatrick if (ObjectType->isRecordType())
7851e5dd7070Spatrick ObjectTypePtrForLookup = ParsedType::make(ObjectType);
7852e5dd7070Spatrick else if (ObjectType->isDependentType())
7853e5dd7070Spatrick ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy);
7854e5dd7070Spatrick }
7855e5dd7070Spatrick
7856e5dd7070Spatrick // Convert the name of the type being destructed (following the ~) into a
7857e5dd7070Spatrick // type (with source-location information).
7858e5dd7070Spatrick QualType DestructedType;
7859e5dd7070Spatrick TypeSourceInfo *DestructedTypeInfo = nullptr;
7860e5dd7070Spatrick PseudoDestructorTypeStorage Destructed;
7861e5dd7070Spatrick if (SecondTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) {
7862e5dd7070Spatrick ParsedType T = getTypeName(*SecondTypeName.Identifier,
7863e5dd7070Spatrick SecondTypeName.StartLocation,
7864e5dd7070Spatrick S, &SS, true, false, ObjectTypePtrForLookup,
7865e5dd7070Spatrick /*IsCtorOrDtorName*/true);
7866e5dd7070Spatrick if (!T &&
7867e5dd7070Spatrick ((SS.isSet() && !computeDeclContext(SS, false)) ||
7868e5dd7070Spatrick (!SS.isSet() && ObjectType->isDependentType()))) {
7869e5dd7070Spatrick // The name of the type being destroyed is a dependent name, and we
7870e5dd7070Spatrick // couldn't find anything useful in scope. Just store the identifier and
7871e5dd7070Spatrick // it's location, and we'll perform (qualified) name lookup again at
7872e5dd7070Spatrick // template instantiation time.
7873e5dd7070Spatrick Destructed = PseudoDestructorTypeStorage(SecondTypeName.Identifier,
7874e5dd7070Spatrick SecondTypeName.StartLocation);
7875e5dd7070Spatrick } else if (!T) {
7876e5dd7070Spatrick Diag(SecondTypeName.StartLocation,
7877e5dd7070Spatrick diag::err_pseudo_dtor_destructor_non_type)
7878e5dd7070Spatrick << SecondTypeName.Identifier << ObjectType;
7879e5dd7070Spatrick if (isSFINAEContext())
7880e5dd7070Spatrick return ExprError();
7881e5dd7070Spatrick
7882e5dd7070Spatrick // Recover by assuming we had the right type all along.
7883e5dd7070Spatrick DestructedType = ObjectType;
7884e5dd7070Spatrick } else
7885e5dd7070Spatrick DestructedType = GetTypeFromParser(T, &DestructedTypeInfo);
7886e5dd7070Spatrick } else {
7887e5dd7070Spatrick // Resolve the template-id to a type.
7888e5dd7070Spatrick TemplateIdAnnotation *TemplateId = SecondTypeName.TemplateId;
7889e5dd7070Spatrick ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
7890e5dd7070Spatrick TemplateId->NumArgs);
7891e5dd7070Spatrick TypeResult T = ActOnTemplateIdType(S,
7892e5dd7070Spatrick SS,
7893e5dd7070Spatrick TemplateId->TemplateKWLoc,
7894e5dd7070Spatrick TemplateId->Template,
7895e5dd7070Spatrick TemplateId->Name,
7896e5dd7070Spatrick TemplateId->TemplateNameLoc,
7897e5dd7070Spatrick TemplateId->LAngleLoc,
7898e5dd7070Spatrick TemplateArgsPtr,
7899e5dd7070Spatrick TemplateId->RAngleLoc,
7900e5dd7070Spatrick /*IsCtorOrDtorName*/true);
7901e5dd7070Spatrick if (T.isInvalid() || !T.get()) {
7902e5dd7070Spatrick // Recover by assuming we had the right type all along.
7903e5dd7070Spatrick DestructedType = ObjectType;
7904e5dd7070Spatrick } else
7905e5dd7070Spatrick DestructedType = GetTypeFromParser(T.get(), &DestructedTypeInfo);
7906e5dd7070Spatrick }
7907e5dd7070Spatrick
7908e5dd7070Spatrick // If we've performed some kind of recovery, (re-)build the type source
7909e5dd7070Spatrick // information.
7910e5dd7070Spatrick if (!DestructedType.isNull()) {
7911e5dd7070Spatrick if (!DestructedTypeInfo)
7912e5dd7070Spatrick DestructedTypeInfo = Context.getTrivialTypeSourceInfo(DestructedType,
7913e5dd7070Spatrick SecondTypeName.StartLocation);
7914e5dd7070Spatrick Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
7915e5dd7070Spatrick }
7916e5dd7070Spatrick
7917e5dd7070Spatrick // Convert the name of the scope type (the type prior to '::') into a type.
7918e5dd7070Spatrick TypeSourceInfo *ScopeTypeInfo = nullptr;
7919e5dd7070Spatrick QualType ScopeType;
7920e5dd7070Spatrick if (FirstTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId ||
7921e5dd7070Spatrick FirstTypeName.Identifier) {
7922e5dd7070Spatrick if (FirstTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) {
7923e5dd7070Spatrick ParsedType T = getTypeName(*FirstTypeName.Identifier,
7924e5dd7070Spatrick FirstTypeName.StartLocation,
7925e5dd7070Spatrick S, &SS, true, false, ObjectTypePtrForLookup,
7926e5dd7070Spatrick /*IsCtorOrDtorName*/true);
7927e5dd7070Spatrick if (!T) {
7928e5dd7070Spatrick Diag(FirstTypeName.StartLocation,
7929e5dd7070Spatrick diag::err_pseudo_dtor_destructor_non_type)
7930e5dd7070Spatrick << FirstTypeName.Identifier << ObjectType;
7931e5dd7070Spatrick
7932e5dd7070Spatrick if (isSFINAEContext())
7933e5dd7070Spatrick return ExprError();
7934e5dd7070Spatrick
7935e5dd7070Spatrick // Just drop this type. It's unnecessary anyway.
7936e5dd7070Spatrick ScopeType = QualType();
7937e5dd7070Spatrick } else
7938e5dd7070Spatrick ScopeType = GetTypeFromParser(T, &ScopeTypeInfo);
7939e5dd7070Spatrick } else {
7940e5dd7070Spatrick // Resolve the template-id to a type.
7941e5dd7070Spatrick TemplateIdAnnotation *TemplateId = FirstTypeName.TemplateId;
7942e5dd7070Spatrick ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
7943e5dd7070Spatrick TemplateId->NumArgs);
7944e5dd7070Spatrick TypeResult T = ActOnTemplateIdType(S,
7945e5dd7070Spatrick SS,
7946e5dd7070Spatrick TemplateId->TemplateKWLoc,
7947e5dd7070Spatrick TemplateId->Template,
7948e5dd7070Spatrick TemplateId->Name,
7949e5dd7070Spatrick TemplateId->TemplateNameLoc,
7950e5dd7070Spatrick TemplateId->LAngleLoc,
7951e5dd7070Spatrick TemplateArgsPtr,
7952e5dd7070Spatrick TemplateId->RAngleLoc,
7953e5dd7070Spatrick /*IsCtorOrDtorName*/true);
7954e5dd7070Spatrick if (T.isInvalid() || !T.get()) {
7955e5dd7070Spatrick // Recover by dropping this type.
7956e5dd7070Spatrick ScopeType = QualType();
7957e5dd7070Spatrick } else
7958e5dd7070Spatrick ScopeType = GetTypeFromParser(T.get(), &ScopeTypeInfo);
7959e5dd7070Spatrick }
7960e5dd7070Spatrick }
7961e5dd7070Spatrick
7962e5dd7070Spatrick if (!ScopeType.isNull() && !ScopeTypeInfo)
7963e5dd7070Spatrick ScopeTypeInfo = Context.getTrivialTypeSourceInfo(ScopeType,
7964e5dd7070Spatrick FirstTypeName.StartLocation);
7965e5dd7070Spatrick
7966e5dd7070Spatrick
7967e5dd7070Spatrick return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, SS,
7968e5dd7070Spatrick ScopeTypeInfo, CCLoc, TildeLoc,
7969e5dd7070Spatrick Destructed);
7970e5dd7070Spatrick }
7971e5dd7070Spatrick
ActOnPseudoDestructorExpr(Scope * S,Expr * Base,SourceLocation OpLoc,tok::TokenKind OpKind,SourceLocation TildeLoc,const DeclSpec & DS)7972e5dd7070Spatrick ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
7973e5dd7070Spatrick SourceLocation OpLoc,
7974e5dd7070Spatrick tok::TokenKind OpKind,
7975e5dd7070Spatrick SourceLocation TildeLoc,
7976e5dd7070Spatrick const DeclSpec& DS) {
7977e5dd7070Spatrick QualType ObjectType;
7978e5dd7070Spatrick if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
7979e5dd7070Spatrick return ExprError();
7980e5dd7070Spatrick
7981a9ac8606Spatrick if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto) {
7982a9ac8606Spatrick Diag(DS.getTypeSpecTypeLoc(), diag::err_decltype_auto_invalid);
7983a9ac8606Spatrick return true;
7984a9ac8606Spatrick }
7985a9ac8606Spatrick
7986*12c85518Srobert QualType T = BuildDecltypeType(DS.getRepAsExpr(), /*AsUnevaluated=*/false);
7987e5dd7070Spatrick
7988e5dd7070Spatrick TypeLocBuilder TLB;
7989e5dd7070Spatrick DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T);
7990*12c85518Srobert DecltypeTL.setDecltypeLoc(DS.getTypeSpecTypeLoc());
7991*12c85518Srobert DecltypeTL.setRParenLoc(DS.getTypeofParensRange().getEnd());
7992e5dd7070Spatrick TypeSourceInfo *DestructedTypeInfo = TLB.getTypeSourceInfo(Context, T);
7993e5dd7070Spatrick PseudoDestructorTypeStorage Destructed(DestructedTypeInfo);
7994e5dd7070Spatrick
7995e5dd7070Spatrick return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, CXXScopeSpec(),
7996e5dd7070Spatrick nullptr, SourceLocation(), TildeLoc,
7997e5dd7070Spatrick Destructed);
7998e5dd7070Spatrick }
7999e5dd7070Spatrick
BuildCXXMemberCallExpr(Expr * E,NamedDecl * FoundDecl,CXXConversionDecl * Method,bool HadMultipleCandidates)8000e5dd7070Spatrick ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
8001e5dd7070Spatrick CXXConversionDecl *Method,
8002e5dd7070Spatrick bool HadMultipleCandidates) {
8003e5dd7070Spatrick // Convert the expression to match the conversion function's implicit object
8004e5dd7070Spatrick // parameter.
8005e5dd7070Spatrick ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/nullptr,
8006e5dd7070Spatrick FoundDecl, Method);
8007e5dd7070Spatrick if (Exp.isInvalid())
8008e5dd7070Spatrick return true;
8009e5dd7070Spatrick
8010e5dd7070Spatrick if (Method->getParent()->isLambda() &&
8011e5dd7070Spatrick Method->getConversionType()->isBlockPointerType()) {
8012e5dd7070Spatrick // This is a lambda conversion to block pointer; check if the argument
8013e5dd7070Spatrick // was a LambdaExpr.
8014e5dd7070Spatrick Expr *SubE = E;
8015e5dd7070Spatrick CastExpr *CE = dyn_cast<CastExpr>(SubE);
8016e5dd7070Spatrick if (CE && CE->getCastKind() == CK_NoOp)
8017e5dd7070Spatrick SubE = CE->getSubExpr();
8018e5dd7070Spatrick SubE = SubE->IgnoreParens();
8019e5dd7070Spatrick if (CXXBindTemporaryExpr *BE = dyn_cast<CXXBindTemporaryExpr>(SubE))
8020e5dd7070Spatrick SubE = BE->getSubExpr();
8021e5dd7070Spatrick if (isa<LambdaExpr>(SubE)) {
8022e5dd7070Spatrick // For the conversion to block pointer on a lambda expression, we
8023e5dd7070Spatrick // construct a special BlockLiteral instead; this doesn't really make
8024e5dd7070Spatrick // a difference in ARC, but outside of ARC the resulting block literal
8025e5dd7070Spatrick // follows the normal lifetime rules for block literals instead of being
8026e5dd7070Spatrick // autoreleased.
8027e5dd7070Spatrick PushExpressionEvaluationContext(
8028e5dd7070Spatrick ExpressionEvaluationContext::PotentiallyEvaluated);
8029e5dd7070Spatrick ExprResult BlockExp = BuildBlockForLambdaConversion(
8030e5dd7070Spatrick Exp.get()->getExprLoc(), Exp.get()->getExprLoc(), Method, Exp.get());
8031e5dd7070Spatrick PopExpressionEvaluationContext();
8032e5dd7070Spatrick
8033ec727ea7Spatrick // FIXME: This note should be produced by a CodeSynthesisContext.
8034e5dd7070Spatrick if (BlockExp.isInvalid())
8035e5dd7070Spatrick Diag(Exp.get()->getExprLoc(), diag::note_lambda_to_block_conv);
8036e5dd7070Spatrick return BlockExp;
8037e5dd7070Spatrick }
8038e5dd7070Spatrick }
8039e5dd7070Spatrick
8040e5dd7070Spatrick MemberExpr *ME =
8041e5dd7070Spatrick BuildMemberExpr(Exp.get(), /*IsArrow=*/false, SourceLocation(),
8042e5dd7070Spatrick NestedNameSpecifierLoc(), SourceLocation(), Method,
8043e5dd7070Spatrick DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()),
8044e5dd7070Spatrick HadMultipleCandidates, DeclarationNameInfo(),
8045a9ac8606Spatrick Context.BoundMemberTy, VK_PRValue, OK_Ordinary);
8046e5dd7070Spatrick
8047e5dd7070Spatrick QualType ResultType = Method->getReturnType();
8048e5dd7070Spatrick ExprValueKind VK = Expr::getValueKindForType(ResultType);
8049e5dd7070Spatrick ResultType = ResultType.getNonLValueExprType(Context);
8050e5dd7070Spatrick
8051e5dd7070Spatrick CXXMemberCallExpr *CE = CXXMemberCallExpr::Create(
8052a9ac8606Spatrick Context, ME, /*Args=*/{}, ResultType, VK, Exp.get()->getEndLoc(),
8053a9ac8606Spatrick CurFPFeatureOverrides());
8054e5dd7070Spatrick
8055e5dd7070Spatrick if (CheckFunctionCall(Method, CE,
8056e5dd7070Spatrick Method->getType()->castAs<FunctionProtoType>()))
8057e5dd7070Spatrick return ExprError();
8058e5dd7070Spatrick
8059a9ac8606Spatrick return CheckForImmediateInvocation(CE, CE->getMethodDecl());
8060e5dd7070Spatrick }
8061e5dd7070Spatrick
BuildCXXNoexceptExpr(SourceLocation KeyLoc,Expr * Operand,SourceLocation RParen)8062e5dd7070Spatrick ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
8063e5dd7070Spatrick SourceLocation RParen) {
8064e5dd7070Spatrick // If the operand is an unresolved lookup expression, the expression is ill-
8065e5dd7070Spatrick // formed per [over.over]p1, because overloaded function names cannot be used
8066e5dd7070Spatrick // without arguments except in explicit contexts.
8067e5dd7070Spatrick ExprResult R = CheckPlaceholderExpr(Operand);
8068e5dd7070Spatrick if (R.isInvalid())
8069e5dd7070Spatrick return R;
8070e5dd7070Spatrick
8071e5dd7070Spatrick R = CheckUnevaluatedOperand(R.get());
8072e5dd7070Spatrick if (R.isInvalid())
8073e5dd7070Spatrick return ExprError();
8074e5dd7070Spatrick
8075e5dd7070Spatrick Operand = R.get();
8076e5dd7070Spatrick
8077a9ac8606Spatrick if (!inTemplateInstantiation() && !Operand->isInstantiationDependent() &&
8078a9ac8606Spatrick Operand->HasSideEffects(Context, false)) {
8079e5dd7070Spatrick // The expression operand for noexcept is in an unevaluated expression
8080e5dd7070Spatrick // context, so side effects could result in unintended consequences.
8081e5dd7070Spatrick Diag(Operand->getExprLoc(), diag::warn_side_effects_unevaluated_context);
8082e5dd7070Spatrick }
8083e5dd7070Spatrick
8084e5dd7070Spatrick CanThrowResult CanThrow = canThrow(Operand);
8085e5dd7070Spatrick return new (Context)
8086e5dd7070Spatrick CXXNoexceptExpr(Context.BoolTy, Operand, CanThrow, KeyLoc, RParen);
8087e5dd7070Spatrick }
8088e5dd7070Spatrick
ActOnNoexceptExpr(SourceLocation KeyLoc,SourceLocation,Expr * Operand,SourceLocation RParen)8089e5dd7070Spatrick ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation,
8090e5dd7070Spatrick Expr *Operand, SourceLocation RParen) {
8091e5dd7070Spatrick return BuildCXXNoexceptExpr(KeyLoc, Operand, RParen);
8092e5dd7070Spatrick }
8093e5dd7070Spatrick
MaybeDecrementCount(Expr * E,llvm::DenseMap<const VarDecl *,int> & RefsMinusAssignments)8094a9ac8606Spatrick static void MaybeDecrementCount(
8095a9ac8606Spatrick Expr *E, llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {
8096a9ac8606Spatrick DeclRefExpr *LHS = nullptr;
8097*12c85518Srobert bool IsCompoundAssign = false;
8098*12c85518Srobert bool isIncrementDecrementUnaryOp = false;
8099a9ac8606Spatrick if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
8100a9ac8606Spatrick if (BO->getLHS()->getType()->isDependentType() ||
8101a9ac8606Spatrick BO->getRHS()->getType()->isDependentType()) {
8102a9ac8606Spatrick if (BO->getOpcode() != BO_Assign)
8103a9ac8606Spatrick return;
8104a9ac8606Spatrick } else if (!BO->isAssignmentOp())
8105a9ac8606Spatrick return;
8106*12c85518Srobert else
8107*12c85518Srobert IsCompoundAssign = BO->isCompoundAssignmentOp();
8108a9ac8606Spatrick LHS = dyn_cast<DeclRefExpr>(BO->getLHS());
8109a9ac8606Spatrick } else if (CXXOperatorCallExpr *COCE = dyn_cast<CXXOperatorCallExpr>(E)) {
8110a9ac8606Spatrick if (COCE->getOperator() != OO_Equal)
8111a9ac8606Spatrick return;
8112a9ac8606Spatrick LHS = dyn_cast<DeclRefExpr>(COCE->getArg(0));
8113*12c85518Srobert } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
8114*12c85518Srobert if (!UO->isIncrementDecrementOp())
8115*12c85518Srobert return;
8116*12c85518Srobert isIncrementDecrementUnaryOp = true;
8117*12c85518Srobert LHS = dyn_cast<DeclRefExpr>(UO->getSubExpr());
8118a9ac8606Spatrick }
8119a9ac8606Spatrick if (!LHS)
8120a9ac8606Spatrick return;
8121a9ac8606Spatrick VarDecl *VD = dyn_cast<VarDecl>(LHS->getDecl());
8122a9ac8606Spatrick if (!VD)
8123a9ac8606Spatrick return;
8124*12c85518Srobert // Don't decrement RefsMinusAssignments if volatile variable with compound
8125*12c85518Srobert // assignment (+=, ...) or increment/decrement unary operator to avoid
8126*12c85518Srobert // potential unused-but-set-variable warning.
8127*12c85518Srobert if ((IsCompoundAssign || isIncrementDecrementUnaryOp) &&
8128*12c85518Srobert VD->getType().isVolatileQualified())
8129*12c85518Srobert return;
8130a9ac8606Spatrick auto iter = RefsMinusAssignments.find(VD);
8131a9ac8606Spatrick if (iter == RefsMinusAssignments.end())
8132a9ac8606Spatrick return;
8133a9ac8606Spatrick iter->getSecond()--;
8134a9ac8606Spatrick }
8135a9ac8606Spatrick
8136e5dd7070Spatrick /// Perform the conversions required for an expression used in a
8137e5dd7070Spatrick /// context that ignores the result.
IgnoredValueConversions(Expr * E)8138e5dd7070Spatrick ExprResult Sema::IgnoredValueConversions(Expr *E) {
8139a9ac8606Spatrick MaybeDecrementCount(E, RefsMinusAssignments);
8140a9ac8606Spatrick
8141e5dd7070Spatrick if (E->hasPlaceholderType()) {
8142e5dd7070Spatrick ExprResult result = CheckPlaceholderExpr(E);
8143e5dd7070Spatrick if (result.isInvalid()) return E;
8144e5dd7070Spatrick E = result.get();
8145e5dd7070Spatrick }
8146e5dd7070Spatrick
8147e5dd7070Spatrick // C99 6.3.2.1:
8148e5dd7070Spatrick // [Except in specific positions,] an lvalue that does not have
8149e5dd7070Spatrick // array type is converted to the value stored in the
8150e5dd7070Spatrick // designated object (and is no longer an lvalue).
8151a9ac8606Spatrick if (E->isPRValue()) {
8152e5dd7070Spatrick // In C, function designators (i.e. expressions of function type)
8153e5dd7070Spatrick // are r-values, but we still want to do function-to-pointer decay
8154e5dd7070Spatrick // on them. This is both technically correct and convenient for
8155e5dd7070Spatrick // some clients.
8156e5dd7070Spatrick if (!getLangOpts().CPlusPlus && E->getType()->isFunctionType())
8157e5dd7070Spatrick return DefaultFunctionArrayConversion(E);
8158e5dd7070Spatrick
8159e5dd7070Spatrick return E;
8160e5dd7070Spatrick }
8161e5dd7070Spatrick
8162e5dd7070Spatrick if (getLangOpts().CPlusPlus) {
8163e5dd7070Spatrick // The C++11 standard defines the notion of a discarded-value expression;
8164e5dd7070Spatrick // normally, we don't need to do anything to handle it, but if it is a
8165e5dd7070Spatrick // volatile lvalue with a special form, we perform an lvalue-to-rvalue
8166e5dd7070Spatrick // conversion.
8167ec727ea7Spatrick if (getLangOpts().CPlusPlus11 && E->isReadIfDiscardedInCPlusPlus11()) {
8168e5dd7070Spatrick ExprResult Res = DefaultLvalueConversion(E);
8169e5dd7070Spatrick if (Res.isInvalid())
8170e5dd7070Spatrick return E;
8171e5dd7070Spatrick E = Res.get();
8172e5dd7070Spatrick } else {
8173e5dd7070Spatrick // Per C++2a [expr.ass]p5, a volatile assignment is not deprecated if
8174e5dd7070Spatrick // it occurs as a discarded-value expression.
8175e5dd7070Spatrick CheckUnusedVolatileAssignment(E);
8176e5dd7070Spatrick }
8177e5dd7070Spatrick
8178e5dd7070Spatrick // C++1z:
8179e5dd7070Spatrick // If the expression is a prvalue after this optional conversion, the
8180e5dd7070Spatrick // temporary materialization conversion is applied.
8181e5dd7070Spatrick //
8182e5dd7070Spatrick // We skip this step: IR generation is able to synthesize the storage for
8183e5dd7070Spatrick // itself in the aggregate case, and adding the extra node to the AST is
8184e5dd7070Spatrick // just clutter.
8185e5dd7070Spatrick // FIXME: We don't emit lifetime markers for the temporaries due to this.
8186e5dd7070Spatrick // FIXME: Do any other AST consumers care about this?
8187e5dd7070Spatrick return E;
8188e5dd7070Spatrick }
8189e5dd7070Spatrick
8190e5dd7070Spatrick // GCC seems to also exclude expressions of incomplete enum type.
8191e5dd7070Spatrick if (const EnumType *T = E->getType()->getAs<EnumType>()) {
8192e5dd7070Spatrick if (!T->getDecl()->isComplete()) {
8193e5dd7070Spatrick // FIXME: stupid workaround for a codegen bug!
8194e5dd7070Spatrick E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get();
8195e5dd7070Spatrick return E;
8196e5dd7070Spatrick }
8197e5dd7070Spatrick }
8198e5dd7070Spatrick
8199e5dd7070Spatrick ExprResult Res = DefaultFunctionArrayLvalueConversion(E);
8200e5dd7070Spatrick if (Res.isInvalid())
8201e5dd7070Spatrick return E;
8202e5dd7070Spatrick E = Res.get();
8203e5dd7070Spatrick
8204e5dd7070Spatrick if (!E->getType()->isVoidType())
8205e5dd7070Spatrick RequireCompleteType(E->getExprLoc(), E->getType(),
8206e5dd7070Spatrick diag::err_incomplete_type);
8207e5dd7070Spatrick return E;
8208e5dd7070Spatrick }
8209e5dd7070Spatrick
CheckUnevaluatedOperand(Expr * E)8210e5dd7070Spatrick ExprResult Sema::CheckUnevaluatedOperand(Expr *E) {
8211e5dd7070Spatrick // Per C++2a [expr.ass]p5, a volatile assignment is not deprecated if
8212e5dd7070Spatrick // it occurs as an unevaluated operand.
8213e5dd7070Spatrick CheckUnusedVolatileAssignment(E);
8214e5dd7070Spatrick
8215e5dd7070Spatrick return E;
8216e5dd7070Spatrick }
8217e5dd7070Spatrick
8218e5dd7070Spatrick // If we can unambiguously determine whether Var can never be used
8219e5dd7070Spatrick // in a constant expression, return true.
8220e5dd7070Spatrick // - if the variable and its initializer are non-dependent, then
8221e5dd7070Spatrick // we can unambiguously check if the variable is a constant expression.
8222e5dd7070Spatrick // - if the initializer is not value dependent - we can determine whether
8223e5dd7070Spatrick // it can be used to initialize a constant expression. If Init can not
8224e5dd7070Spatrick // be used to initialize a constant expression we conclude that Var can
8225e5dd7070Spatrick // never be a constant expression.
8226e5dd7070Spatrick // - FXIME: if the initializer is dependent, we can still do some analysis and
8227e5dd7070Spatrick // identify certain cases unambiguously as non-const by using a Visitor:
8228e5dd7070Spatrick // - such as those that involve odr-use of a ParmVarDecl, involve a new
8229e5dd7070Spatrick // delete, lambda-expr, dynamic-cast, reinterpret-cast etc...
VariableCanNeverBeAConstantExpression(VarDecl * Var,ASTContext & Context)8230e5dd7070Spatrick static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var,
8231e5dd7070Spatrick ASTContext &Context) {
8232e5dd7070Spatrick if (isa<ParmVarDecl>(Var)) return true;
8233e5dd7070Spatrick const VarDecl *DefVD = nullptr;
8234e5dd7070Spatrick
8235e5dd7070Spatrick // If there is no initializer - this can not be a constant expression.
8236e5dd7070Spatrick if (!Var->getAnyInitializer(DefVD)) return true;
8237e5dd7070Spatrick assert(DefVD);
8238e5dd7070Spatrick if (DefVD->isWeak()) return false;
8239e5dd7070Spatrick EvaluatedStmt *Eval = DefVD->ensureEvaluatedStmt();
8240e5dd7070Spatrick
8241e5dd7070Spatrick Expr *Init = cast<Expr>(Eval->Value);
8242e5dd7070Spatrick
8243e5dd7070Spatrick if (Var->getType()->isDependentType() || Init->isValueDependent()) {
8244e5dd7070Spatrick // FIXME: Teach the constant evaluator to deal with the non-dependent parts
8245e5dd7070Spatrick // of value-dependent expressions, and use it here to determine whether the
8246e5dd7070Spatrick // initializer is a potential constant expression.
8247e5dd7070Spatrick return false;
8248e5dd7070Spatrick }
8249e5dd7070Spatrick
8250e5dd7070Spatrick return !Var->isUsableInConstantExpressions(Context);
8251e5dd7070Spatrick }
8252e5dd7070Spatrick
8253e5dd7070Spatrick /// Check if the current lambda has any potential captures
8254e5dd7070Spatrick /// that must be captured by any of its enclosing lambdas that are ready to
8255e5dd7070Spatrick /// capture. If there is a lambda that can capture a nested
8256e5dd7070Spatrick /// potential-capture, go ahead and do so. Also, check to see if any
8257e5dd7070Spatrick /// variables are uncaptureable or do not involve an odr-use so do not
8258e5dd7070Spatrick /// need to be captured.
8259e5dd7070Spatrick
CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(Expr * const FE,LambdaScopeInfo * const CurrentLSI,Sema & S)8260e5dd7070Spatrick static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
8261e5dd7070Spatrick Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S) {
8262e5dd7070Spatrick
8263e5dd7070Spatrick assert(!S.isUnevaluatedContext());
8264e5dd7070Spatrick assert(S.CurContext->isDependentContext());
8265e5dd7070Spatrick #ifndef NDEBUG
8266e5dd7070Spatrick DeclContext *DC = S.CurContext;
8267e5dd7070Spatrick while (DC && isa<CapturedDecl>(DC))
8268e5dd7070Spatrick DC = DC->getParent();
8269e5dd7070Spatrick assert(
8270e5dd7070Spatrick CurrentLSI->CallOperator == DC &&
8271e5dd7070Spatrick "The current call operator must be synchronized with Sema's CurContext");
8272e5dd7070Spatrick #endif // NDEBUG
8273e5dd7070Spatrick
8274e5dd7070Spatrick const bool IsFullExprInstantiationDependent = FE->isInstantiationDependent();
8275e5dd7070Spatrick
8276e5dd7070Spatrick // All the potentially captureable variables in the current nested
8277e5dd7070Spatrick // lambda (within a generic outer lambda), must be captured by an
8278e5dd7070Spatrick // outer lambda that is enclosed within a non-dependent context.
8279*12c85518Srobert CurrentLSI->visitPotentialCaptures([&](ValueDecl *Var, Expr *VarExpr) {
8280e5dd7070Spatrick // If the variable is clearly identified as non-odr-used and the full
8281e5dd7070Spatrick // expression is not instantiation dependent, only then do we not
8282e5dd7070Spatrick // need to check enclosing lambda's for speculative captures.
8283e5dd7070Spatrick // For e.g.:
8284e5dd7070Spatrick // Even though 'x' is not odr-used, it should be captured.
8285e5dd7070Spatrick // int test() {
8286e5dd7070Spatrick // const int x = 10;
8287e5dd7070Spatrick // auto L = [=](auto a) {
8288e5dd7070Spatrick // (void) +x + a;
8289e5dd7070Spatrick // };
8290e5dd7070Spatrick // }
8291e5dd7070Spatrick if (CurrentLSI->isVariableExprMarkedAsNonODRUsed(VarExpr) &&
8292e5dd7070Spatrick !IsFullExprInstantiationDependent)
8293e5dd7070Spatrick return;
8294e5dd7070Spatrick
8295*12c85518Srobert VarDecl *UnderlyingVar = Var->getPotentiallyDecomposedVarDecl();
8296*12c85518Srobert if (!UnderlyingVar)
8297*12c85518Srobert return;
8298*12c85518Srobert
8299e5dd7070Spatrick // If we have a capture-capable lambda for the variable, go ahead and
8300e5dd7070Spatrick // capture the variable in that lambda (and all its enclosing lambdas).
8301*12c85518Srobert if (const std::optional<unsigned> Index =
8302e5dd7070Spatrick getStackIndexOfNearestEnclosingCaptureCapableLambda(
8303e5dd7070Spatrick S.FunctionScopes, Var, S))
8304*12c85518Srobert S.MarkCaptureUsedInEnclosingContext(Var, VarExpr->getExprLoc(), *Index);
8305e5dd7070Spatrick const bool IsVarNeverAConstantExpression =
8306*12c85518Srobert VariableCanNeverBeAConstantExpression(UnderlyingVar, S.Context);
8307e5dd7070Spatrick if (!IsFullExprInstantiationDependent || IsVarNeverAConstantExpression) {
8308e5dd7070Spatrick // This full expression is not instantiation dependent or the variable
8309e5dd7070Spatrick // can not be used in a constant expression - which means
8310e5dd7070Spatrick // this variable must be odr-used here, so diagnose a
8311e5dd7070Spatrick // capture violation early, if the variable is un-captureable.
8312e5dd7070Spatrick // This is purely for diagnosing errors early. Otherwise, this
8313e5dd7070Spatrick // error would get diagnosed when the lambda becomes capture ready.
8314e5dd7070Spatrick QualType CaptureType, DeclRefType;
8315e5dd7070Spatrick SourceLocation ExprLoc = VarExpr->getExprLoc();
8316e5dd7070Spatrick if (S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit,
8317e5dd7070Spatrick /*EllipsisLoc*/ SourceLocation(),
8318e5dd7070Spatrick /*BuildAndDiagnose*/false, CaptureType,
8319e5dd7070Spatrick DeclRefType, nullptr)) {
8320e5dd7070Spatrick // We will never be able to capture this variable, and we need
8321e5dd7070Spatrick // to be able to in any and all instantiations, so diagnose it.
8322e5dd7070Spatrick S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit,
8323e5dd7070Spatrick /*EllipsisLoc*/ SourceLocation(),
8324e5dd7070Spatrick /*BuildAndDiagnose*/true, CaptureType,
8325e5dd7070Spatrick DeclRefType, nullptr);
8326e5dd7070Spatrick }
8327e5dd7070Spatrick }
8328e5dd7070Spatrick });
8329e5dd7070Spatrick
8330e5dd7070Spatrick // Check if 'this' needs to be captured.
8331e5dd7070Spatrick if (CurrentLSI->hasPotentialThisCapture()) {
8332e5dd7070Spatrick // If we have a capture-capable lambda for 'this', go ahead and capture
8333e5dd7070Spatrick // 'this' in that lambda (and all its enclosing lambdas).
8334*12c85518Srobert if (const std::optional<unsigned> Index =
8335e5dd7070Spatrick getStackIndexOfNearestEnclosingCaptureCapableLambda(
8336e5dd7070Spatrick S.FunctionScopes, /*0 is 'this'*/ nullptr, S)) {
8337*12c85518Srobert const unsigned FunctionScopeIndexOfCapturableLambda = *Index;
8338e5dd7070Spatrick S.CheckCXXThisCapture(CurrentLSI->PotentialThisCaptureLocation,
8339e5dd7070Spatrick /*Explicit*/ false, /*BuildAndDiagnose*/ true,
8340e5dd7070Spatrick &FunctionScopeIndexOfCapturableLambda);
8341e5dd7070Spatrick }
8342e5dd7070Spatrick }
8343e5dd7070Spatrick
8344e5dd7070Spatrick // Reset all the potential captures at the end of each full-expression.
8345e5dd7070Spatrick CurrentLSI->clearPotentialCaptures();
8346e5dd7070Spatrick }
8347e5dd7070Spatrick
attemptRecovery(Sema & SemaRef,const TypoCorrectionConsumer & Consumer,const TypoCorrection & TC)8348e5dd7070Spatrick static ExprResult attemptRecovery(Sema &SemaRef,
8349e5dd7070Spatrick const TypoCorrectionConsumer &Consumer,
8350e5dd7070Spatrick const TypoCorrection &TC) {
8351e5dd7070Spatrick LookupResult R(SemaRef, Consumer.getLookupResult().getLookupNameInfo(),
8352e5dd7070Spatrick Consumer.getLookupResult().getLookupKind());
8353e5dd7070Spatrick const CXXScopeSpec *SS = Consumer.getSS();
8354e5dd7070Spatrick CXXScopeSpec NewSS;
8355e5dd7070Spatrick
8356e5dd7070Spatrick // Use an approprate CXXScopeSpec for building the expr.
8357e5dd7070Spatrick if (auto *NNS = TC.getCorrectionSpecifier())
8358e5dd7070Spatrick NewSS.MakeTrivial(SemaRef.Context, NNS, TC.getCorrectionRange());
8359e5dd7070Spatrick else if (SS && !TC.WillReplaceSpecifier())
8360e5dd7070Spatrick NewSS = *SS;
8361e5dd7070Spatrick
8362e5dd7070Spatrick if (auto *ND = TC.getFoundDecl()) {
8363e5dd7070Spatrick R.setLookupName(ND->getDeclName());
8364e5dd7070Spatrick R.addDecl(ND);
8365e5dd7070Spatrick if (ND->isCXXClassMember()) {
8366e5dd7070Spatrick // Figure out the correct naming class to add to the LookupResult.
8367e5dd7070Spatrick CXXRecordDecl *Record = nullptr;
8368e5dd7070Spatrick if (auto *NNS = TC.getCorrectionSpecifier())
8369e5dd7070Spatrick Record = NNS->getAsType()->getAsCXXRecordDecl();
8370e5dd7070Spatrick if (!Record)
8371e5dd7070Spatrick Record =
8372e5dd7070Spatrick dyn_cast<CXXRecordDecl>(ND->getDeclContext()->getRedeclContext());
8373e5dd7070Spatrick if (Record)
8374e5dd7070Spatrick R.setNamingClass(Record);
8375e5dd7070Spatrick
8376e5dd7070Spatrick // Detect and handle the case where the decl might be an implicit
8377e5dd7070Spatrick // member.
8378e5dd7070Spatrick bool MightBeImplicitMember;
8379e5dd7070Spatrick if (!Consumer.isAddressOfOperand())
8380e5dd7070Spatrick MightBeImplicitMember = true;
8381e5dd7070Spatrick else if (!NewSS.isEmpty())
8382e5dd7070Spatrick MightBeImplicitMember = false;
8383e5dd7070Spatrick else if (R.isOverloadedResult())
8384e5dd7070Spatrick MightBeImplicitMember = false;
8385e5dd7070Spatrick else if (R.isUnresolvableResult())
8386e5dd7070Spatrick MightBeImplicitMember = true;
8387e5dd7070Spatrick else
8388e5dd7070Spatrick MightBeImplicitMember = isa<FieldDecl>(ND) ||
8389e5dd7070Spatrick isa<IndirectFieldDecl>(ND) ||
8390e5dd7070Spatrick isa<MSPropertyDecl>(ND);
8391e5dd7070Spatrick
8392e5dd7070Spatrick if (MightBeImplicitMember)
8393e5dd7070Spatrick return SemaRef.BuildPossibleImplicitMemberExpr(
8394e5dd7070Spatrick NewSS, /*TemplateKWLoc*/ SourceLocation(), R,
8395e5dd7070Spatrick /*TemplateArgs*/ nullptr, /*S*/ nullptr);
8396e5dd7070Spatrick } else if (auto *Ivar = dyn_cast<ObjCIvarDecl>(ND)) {
8397e5dd7070Spatrick return SemaRef.LookupInObjCMethod(R, Consumer.getScope(),
8398e5dd7070Spatrick Ivar->getIdentifier());
8399e5dd7070Spatrick }
8400e5dd7070Spatrick }
8401e5dd7070Spatrick
8402e5dd7070Spatrick return SemaRef.BuildDeclarationNameExpr(NewSS, R, /*NeedsADL*/ false,
8403e5dd7070Spatrick /*AcceptInvalidDecl*/ true);
8404e5dd7070Spatrick }
8405e5dd7070Spatrick
8406e5dd7070Spatrick namespace {
8407e5dd7070Spatrick class FindTypoExprs : public RecursiveASTVisitor<FindTypoExprs> {
8408e5dd7070Spatrick llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs;
8409e5dd7070Spatrick
8410e5dd7070Spatrick public:
FindTypoExprs(llvm::SmallSetVector<TypoExpr *,2> & TypoExprs)8411e5dd7070Spatrick explicit FindTypoExprs(llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs)
8412e5dd7070Spatrick : TypoExprs(TypoExprs) {}
VisitTypoExpr(TypoExpr * TE)8413e5dd7070Spatrick bool VisitTypoExpr(TypoExpr *TE) {
8414e5dd7070Spatrick TypoExprs.insert(TE);
8415e5dd7070Spatrick return true;
8416e5dd7070Spatrick }
8417e5dd7070Spatrick };
8418e5dd7070Spatrick
8419e5dd7070Spatrick class TransformTypos : public TreeTransform<TransformTypos> {
8420e5dd7070Spatrick typedef TreeTransform<TransformTypos> BaseTransform;
8421e5dd7070Spatrick
8422e5dd7070Spatrick VarDecl *InitDecl; // A decl to avoid as a correction because it is in the
8423e5dd7070Spatrick // process of being initialized.
8424e5dd7070Spatrick llvm::function_ref<ExprResult(Expr *)> ExprFilter;
8425e5dd7070Spatrick llvm::SmallSetVector<TypoExpr *, 2> TypoExprs, AmbiguousTypoExprs;
8426e5dd7070Spatrick llvm::SmallDenseMap<TypoExpr *, ExprResult, 2> TransformCache;
8427e5dd7070Spatrick llvm::SmallDenseMap<OverloadExpr *, Expr *, 4> OverloadResolution;
8428e5dd7070Spatrick
8429e5dd7070Spatrick /// Emit diagnostics for all of the TypoExprs encountered.
8430e5dd7070Spatrick ///
8431e5dd7070Spatrick /// If the TypoExprs were successfully corrected, then the diagnostics should
8432e5dd7070Spatrick /// suggest the corrections. Otherwise the diagnostics will not suggest
8433e5dd7070Spatrick /// anything (having been passed an empty TypoCorrection).
8434e5dd7070Spatrick ///
8435e5dd7070Spatrick /// If we've failed to correct due to ambiguous corrections, we need to
8436e5dd7070Spatrick /// be sure to pass empty corrections and replacements. Otherwise it's
8437e5dd7070Spatrick /// possible that the Consumer has a TypoCorrection that failed to ambiguity
8438e5dd7070Spatrick /// and we don't want to report those diagnostics.
EmitAllDiagnostics(bool IsAmbiguous)8439e5dd7070Spatrick void EmitAllDiagnostics(bool IsAmbiguous) {
8440e5dd7070Spatrick for (TypoExpr *TE : TypoExprs) {
8441e5dd7070Spatrick auto &State = SemaRef.getTypoExprState(TE);
8442e5dd7070Spatrick if (State.DiagHandler) {
8443e5dd7070Spatrick TypoCorrection TC = IsAmbiguous
8444e5dd7070Spatrick ? TypoCorrection() : State.Consumer->getCurrentCorrection();
8445e5dd7070Spatrick ExprResult Replacement = IsAmbiguous ? ExprError() : TransformCache[TE];
8446e5dd7070Spatrick
8447e5dd7070Spatrick // Extract the NamedDecl from the transformed TypoExpr and add it to the
8448e5dd7070Spatrick // TypoCorrection, replacing the existing decls. This ensures the right
8449e5dd7070Spatrick // NamedDecl is used in diagnostics e.g. in the case where overload
8450e5dd7070Spatrick // resolution was used to select one from several possible decls that
8451e5dd7070Spatrick // had been stored in the TypoCorrection.
8452e5dd7070Spatrick if (auto *ND = getDeclFromExpr(
8453e5dd7070Spatrick Replacement.isInvalid() ? nullptr : Replacement.get()))
8454e5dd7070Spatrick TC.setCorrectionDecl(ND);
8455e5dd7070Spatrick
8456e5dd7070Spatrick State.DiagHandler(TC);
8457e5dd7070Spatrick }
8458e5dd7070Spatrick SemaRef.clearDelayedTypo(TE);
8459e5dd7070Spatrick }
8460e5dd7070Spatrick }
8461e5dd7070Spatrick
8462ec727ea7Spatrick /// Try to advance the typo correction state of the first unfinished TypoExpr.
8463ec727ea7Spatrick /// We allow advancement of the correction stream by removing it from the
8464ec727ea7Spatrick /// TransformCache which allows `TransformTypoExpr` to advance during the
8465ec727ea7Spatrick /// next transformation attempt.
8466ec727ea7Spatrick ///
8467ec727ea7Spatrick /// Any substitution attempts for the previous TypoExprs (which must have been
8468ec727ea7Spatrick /// finished) will need to be retried since it's possible that they will now
8469ec727ea7Spatrick /// be invalid given the latest advancement.
8470ec727ea7Spatrick ///
8471ec727ea7Spatrick /// We need to be sure that we're making progress - it's possible that the
8472ec727ea7Spatrick /// tree is so malformed that the transform never makes it to the
8473ec727ea7Spatrick /// `TransformTypoExpr`.
8474ec727ea7Spatrick ///
8475ec727ea7Spatrick /// Returns true if there are any untried correction combinations.
CheckAndAdvanceTypoExprCorrectionStreams()8476e5dd7070Spatrick bool CheckAndAdvanceTypoExprCorrectionStreams() {
8477*12c85518Srobert for (auto *TE : TypoExprs) {
8478e5dd7070Spatrick auto &State = SemaRef.getTypoExprState(TE);
8479e5dd7070Spatrick TransformCache.erase(TE);
8480ec727ea7Spatrick if (!State.Consumer->hasMadeAnyCorrectionProgress())
8481ec727ea7Spatrick return false;
8482e5dd7070Spatrick if (!State.Consumer->finished())
8483e5dd7070Spatrick return true;
8484e5dd7070Spatrick State.Consumer->resetCorrectionStream();
8485e5dd7070Spatrick }
8486e5dd7070Spatrick return false;
8487e5dd7070Spatrick }
8488e5dd7070Spatrick
getDeclFromExpr(Expr * E)8489e5dd7070Spatrick NamedDecl *getDeclFromExpr(Expr *E) {
8490e5dd7070Spatrick if (auto *OE = dyn_cast_or_null<OverloadExpr>(E))
8491e5dd7070Spatrick E = OverloadResolution[OE];
8492e5dd7070Spatrick
8493e5dd7070Spatrick if (!E)
8494e5dd7070Spatrick return nullptr;
8495e5dd7070Spatrick if (auto *DRE = dyn_cast<DeclRefExpr>(E))
8496e5dd7070Spatrick return DRE->getFoundDecl();
8497e5dd7070Spatrick if (auto *ME = dyn_cast<MemberExpr>(E))
8498e5dd7070Spatrick return ME->getFoundDecl();
8499*12c85518Srobert // FIXME: Add any other expr types that could be seen by the delayed typo
8500e5dd7070Spatrick // correction TreeTransform for which the corresponding TypoCorrection could
8501e5dd7070Spatrick // contain multiple decls.
8502e5dd7070Spatrick return nullptr;
8503e5dd7070Spatrick }
8504e5dd7070Spatrick
TryTransform(Expr * E)8505e5dd7070Spatrick ExprResult TryTransform(Expr *E) {
8506e5dd7070Spatrick Sema::SFINAETrap Trap(SemaRef);
8507e5dd7070Spatrick ExprResult Res = TransformExpr(E);
8508e5dd7070Spatrick if (Trap.hasErrorOccurred() || Res.isInvalid())
8509e5dd7070Spatrick return ExprError();
8510e5dd7070Spatrick
8511e5dd7070Spatrick return ExprFilter(Res.get());
8512e5dd7070Spatrick }
8513e5dd7070Spatrick
8514e5dd7070Spatrick // Since correcting typos may intoduce new TypoExprs, this function
8515e5dd7070Spatrick // checks for new TypoExprs and recurses if it finds any. Note that it will
8516e5dd7070Spatrick // only succeed if it is able to correct all typos in the given expression.
CheckForRecursiveTypos(ExprResult Res,bool & IsAmbiguous)8517e5dd7070Spatrick ExprResult CheckForRecursiveTypos(ExprResult Res, bool &IsAmbiguous) {
8518e5dd7070Spatrick if (Res.isInvalid()) {
8519e5dd7070Spatrick return Res;
8520e5dd7070Spatrick }
8521e5dd7070Spatrick // Check to see if any new TypoExprs were created. If so, we need to recurse
8522e5dd7070Spatrick // to check their validity.
8523e5dd7070Spatrick Expr *FixedExpr = Res.get();
8524e5dd7070Spatrick
8525e5dd7070Spatrick auto SavedTypoExprs = std::move(TypoExprs);
8526e5dd7070Spatrick auto SavedAmbiguousTypoExprs = std::move(AmbiguousTypoExprs);
8527e5dd7070Spatrick TypoExprs.clear();
8528e5dd7070Spatrick AmbiguousTypoExprs.clear();
8529e5dd7070Spatrick
8530e5dd7070Spatrick FindTypoExprs(TypoExprs).TraverseStmt(FixedExpr);
8531e5dd7070Spatrick if (!TypoExprs.empty()) {
8532e5dd7070Spatrick // Recurse to handle newly created TypoExprs. If we're not able to
8533e5dd7070Spatrick // handle them, discard these TypoExprs.
8534e5dd7070Spatrick ExprResult RecurResult =
8535e5dd7070Spatrick RecursiveTransformLoop(FixedExpr, IsAmbiguous);
8536e5dd7070Spatrick if (RecurResult.isInvalid()) {
8537e5dd7070Spatrick Res = ExprError();
8538e5dd7070Spatrick // Recursive corrections didn't work, wipe them away and don't add
8539e5dd7070Spatrick // them to the TypoExprs set. Remove them from Sema's TypoExpr list
8540e5dd7070Spatrick // since we don't want to clear them twice. Note: it's possible the
8541e5dd7070Spatrick // TypoExprs were created recursively and thus won't be in our
8542e5dd7070Spatrick // Sema's TypoExprs - they were created in our `RecursiveTransformLoop`.
8543e5dd7070Spatrick auto &SemaTypoExprs = SemaRef.TypoExprs;
8544*12c85518Srobert for (auto *TE : TypoExprs) {
8545e5dd7070Spatrick TransformCache.erase(TE);
8546e5dd7070Spatrick SemaRef.clearDelayedTypo(TE);
8547e5dd7070Spatrick
8548e5dd7070Spatrick auto SI = find(SemaTypoExprs, TE);
8549e5dd7070Spatrick if (SI != SemaTypoExprs.end()) {
8550e5dd7070Spatrick SemaTypoExprs.erase(SI);
8551e5dd7070Spatrick }
8552e5dd7070Spatrick }
8553e5dd7070Spatrick } else {
8554e5dd7070Spatrick // TypoExpr is valid: add newly created TypoExprs since we were
8555e5dd7070Spatrick // able to correct them.
8556e5dd7070Spatrick Res = RecurResult;
8557e5dd7070Spatrick SavedTypoExprs.set_union(TypoExprs);
8558e5dd7070Spatrick }
8559e5dd7070Spatrick }
8560e5dd7070Spatrick
8561e5dd7070Spatrick TypoExprs = std::move(SavedTypoExprs);
8562e5dd7070Spatrick AmbiguousTypoExprs = std::move(SavedAmbiguousTypoExprs);
8563e5dd7070Spatrick
8564e5dd7070Spatrick return Res;
8565e5dd7070Spatrick }
8566e5dd7070Spatrick
8567e5dd7070Spatrick // Try to transform the given expression, looping through the correction
8568e5dd7070Spatrick // candidates with `CheckAndAdvanceTypoExprCorrectionStreams`.
8569e5dd7070Spatrick //
8570e5dd7070Spatrick // If valid ambiguous typo corrections are seen, `IsAmbiguous` is set to
8571e5dd7070Spatrick // true and this method immediately will return an `ExprError`.
RecursiveTransformLoop(Expr * E,bool & IsAmbiguous)8572e5dd7070Spatrick ExprResult RecursiveTransformLoop(Expr *E, bool &IsAmbiguous) {
8573e5dd7070Spatrick ExprResult Res;
8574e5dd7070Spatrick auto SavedTypoExprs = std::move(SemaRef.TypoExprs);
8575e5dd7070Spatrick SemaRef.TypoExprs.clear();
8576e5dd7070Spatrick
8577e5dd7070Spatrick while (true) {
8578e5dd7070Spatrick Res = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous);
8579e5dd7070Spatrick
8580e5dd7070Spatrick // Recursion encountered an ambiguous correction. This means that our
8581e5dd7070Spatrick // correction itself is ambiguous, so stop now.
8582e5dd7070Spatrick if (IsAmbiguous)
8583e5dd7070Spatrick break;
8584e5dd7070Spatrick
8585e5dd7070Spatrick // If the transform is still valid after checking for any new typos,
8586e5dd7070Spatrick // it's good to go.
8587e5dd7070Spatrick if (!Res.isInvalid())
8588e5dd7070Spatrick break;
8589e5dd7070Spatrick
8590e5dd7070Spatrick // The transform was invalid, see if we have any TypoExprs with untried
8591e5dd7070Spatrick // correction candidates.
8592e5dd7070Spatrick if (!CheckAndAdvanceTypoExprCorrectionStreams())
8593e5dd7070Spatrick break;
8594e5dd7070Spatrick }
8595e5dd7070Spatrick
8596e5dd7070Spatrick // If we found a valid result, double check to make sure it's not ambiguous.
8597e5dd7070Spatrick if (!IsAmbiguous && !Res.isInvalid() && !AmbiguousTypoExprs.empty()) {
8598e5dd7070Spatrick auto SavedTransformCache =
8599e5dd7070Spatrick llvm::SmallDenseMap<TypoExpr *, ExprResult, 2>(TransformCache);
8600e5dd7070Spatrick
8601e5dd7070Spatrick // Ensure none of the TypoExprs have multiple typo correction candidates
8602e5dd7070Spatrick // with the same edit length that pass all the checks and filters.
8603e5dd7070Spatrick while (!AmbiguousTypoExprs.empty()) {
8604e5dd7070Spatrick auto TE = AmbiguousTypoExprs.back();
8605e5dd7070Spatrick
8606e5dd7070Spatrick // TryTransform itself can create new Typos, adding them to the TypoExpr map
8607e5dd7070Spatrick // and invalidating our TypoExprState, so always fetch it instead of storing.
8608e5dd7070Spatrick SemaRef.getTypoExprState(TE).Consumer->saveCurrentPosition();
8609e5dd7070Spatrick
8610e5dd7070Spatrick TypoCorrection TC = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection();
8611e5dd7070Spatrick TypoCorrection Next;
8612e5dd7070Spatrick do {
8613e5dd7070Spatrick // Fetch the next correction by erasing the typo from the cache and calling
8614e5dd7070Spatrick // `TryTransform` which will iterate through corrections in
8615e5dd7070Spatrick // `TransformTypoExpr`.
8616e5dd7070Spatrick TransformCache.erase(TE);
8617e5dd7070Spatrick ExprResult AmbigRes = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous);
8618e5dd7070Spatrick
8619e5dd7070Spatrick if (!AmbigRes.isInvalid() || IsAmbiguous) {
8620e5dd7070Spatrick SemaRef.getTypoExprState(TE).Consumer->resetCorrectionStream();
8621e5dd7070Spatrick SavedTransformCache.erase(TE);
8622e5dd7070Spatrick Res = ExprError();
8623e5dd7070Spatrick IsAmbiguous = true;
8624e5dd7070Spatrick break;
8625e5dd7070Spatrick }
8626e5dd7070Spatrick } while ((Next = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection()) &&
8627e5dd7070Spatrick Next.getEditDistance(false) == TC.getEditDistance(false));
8628e5dd7070Spatrick
8629e5dd7070Spatrick if (IsAmbiguous)
8630e5dd7070Spatrick break;
8631e5dd7070Spatrick
8632e5dd7070Spatrick AmbiguousTypoExprs.remove(TE);
8633e5dd7070Spatrick SemaRef.getTypoExprState(TE).Consumer->restoreSavedPosition();
8634a9ac8606Spatrick TransformCache[TE] = SavedTransformCache[TE];
8635e5dd7070Spatrick }
8636e5dd7070Spatrick TransformCache = std::move(SavedTransformCache);
8637e5dd7070Spatrick }
8638e5dd7070Spatrick
8639e5dd7070Spatrick // Wipe away any newly created TypoExprs that we don't know about. Since we
8640e5dd7070Spatrick // clear any invalid TypoExprs in `CheckForRecursiveTypos`, this is only
8641e5dd7070Spatrick // possible if a `TypoExpr` is created during a transformation but then
8642e5dd7070Spatrick // fails before we can discover it.
8643e5dd7070Spatrick auto &SemaTypoExprs = SemaRef.TypoExprs;
8644e5dd7070Spatrick for (auto Iterator = SemaTypoExprs.begin(); Iterator != SemaTypoExprs.end();) {
8645e5dd7070Spatrick auto TE = *Iterator;
8646e5dd7070Spatrick auto FI = find(TypoExprs, TE);
8647e5dd7070Spatrick if (FI != TypoExprs.end()) {
8648e5dd7070Spatrick Iterator++;
8649e5dd7070Spatrick continue;
8650e5dd7070Spatrick }
8651e5dd7070Spatrick SemaRef.clearDelayedTypo(TE);
8652e5dd7070Spatrick Iterator = SemaTypoExprs.erase(Iterator);
8653e5dd7070Spatrick }
8654e5dd7070Spatrick SemaRef.TypoExprs = std::move(SavedTypoExprs);
8655e5dd7070Spatrick
8656e5dd7070Spatrick return Res;
8657e5dd7070Spatrick }
8658e5dd7070Spatrick
8659e5dd7070Spatrick public:
TransformTypos(Sema & SemaRef,VarDecl * InitDecl,llvm::function_ref<ExprResult (Expr *)> Filter)8660e5dd7070Spatrick TransformTypos(Sema &SemaRef, VarDecl *InitDecl, llvm::function_ref<ExprResult(Expr *)> Filter)
8661e5dd7070Spatrick : BaseTransform(SemaRef), InitDecl(InitDecl), ExprFilter(Filter) {}
8662e5dd7070Spatrick
RebuildCallExpr(Expr * Callee,SourceLocation LParenLoc,MultiExprArg Args,SourceLocation RParenLoc,Expr * ExecConfig=nullptr)8663e5dd7070Spatrick ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
8664e5dd7070Spatrick MultiExprArg Args,
8665e5dd7070Spatrick SourceLocation RParenLoc,
8666e5dd7070Spatrick Expr *ExecConfig = nullptr) {
8667e5dd7070Spatrick auto Result = BaseTransform::RebuildCallExpr(Callee, LParenLoc, Args,
8668e5dd7070Spatrick RParenLoc, ExecConfig);
8669e5dd7070Spatrick if (auto *OE = dyn_cast<OverloadExpr>(Callee)) {
8670e5dd7070Spatrick if (Result.isUsable()) {
8671e5dd7070Spatrick Expr *ResultCall = Result.get();
8672e5dd7070Spatrick if (auto *BE = dyn_cast<CXXBindTemporaryExpr>(ResultCall))
8673e5dd7070Spatrick ResultCall = BE->getSubExpr();
8674e5dd7070Spatrick if (auto *CE = dyn_cast<CallExpr>(ResultCall))
8675e5dd7070Spatrick OverloadResolution[OE] = CE->getCallee();
8676e5dd7070Spatrick }
8677e5dd7070Spatrick }
8678e5dd7070Spatrick return Result;
8679e5dd7070Spatrick }
8680e5dd7070Spatrick
TransformLambdaExpr(LambdaExpr * E)8681e5dd7070Spatrick ExprResult TransformLambdaExpr(LambdaExpr *E) { return Owned(E); }
8682e5dd7070Spatrick
TransformBlockExpr(BlockExpr * E)8683e5dd7070Spatrick ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); }
8684e5dd7070Spatrick
Transform(Expr * E)8685e5dd7070Spatrick ExprResult Transform(Expr *E) {
8686e5dd7070Spatrick bool IsAmbiguous = false;
8687e5dd7070Spatrick ExprResult Res = RecursiveTransformLoop(E, IsAmbiguous);
8688e5dd7070Spatrick
8689e5dd7070Spatrick if (!Res.isUsable())
8690e5dd7070Spatrick FindTypoExprs(TypoExprs).TraverseStmt(E);
8691e5dd7070Spatrick
8692e5dd7070Spatrick EmitAllDiagnostics(IsAmbiguous);
8693e5dd7070Spatrick
8694e5dd7070Spatrick return Res;
8695e5dd7070Spatrick }
8696e5dd7070Spatrick
TransformTypoExpr(TypoExpr * E)8697e5dd7070Spatrick ExprResult TransformTypoExpr(TypoExpr *E) {
8698e5dd7070Spatrick // If the TypoExpr hasn't been seen before, record it. Otherwise, return the
8699e5dd7070Spatrick // cached transformation result if there is one and the TypoExpr isn't the
8700e5dd7070Spatrick // first one that was encountered.
8701e5dd7070Spatrick auto &CacheEntry = TransformCache[E];
8702e5dd7070Spatrick if (!TypoExprs.insert(E) && !CacheEntry.isUnset()) {
8703e5dd7070Spatrick return CacheEntry;
8704e5dd7070Spatrick }
8705e5dd7070Spatrick
8706e5dd7070Spatrick auto &State = SemaRef.getTypoExprState(E);
8707e5dd7070Spatrick assert(State.Consumer && "Cannot transform a cleared TypoExpr");
8708e5dd7070Spatrick
8709e5dd7070Spatrick // For the first TypoExpr and an uncached TypoExpr, find the next likely
8710e5dd7070Spatrick // typo correction and return it.
8711e5dd7070Spatrick while (TypoCorrection TC = State.Consumer->getNextCorrection()) {
8712e5dd7070Spatrick if (InitDecl && TC.getFoundDecl() == InitDecl)
8713e5dd7070Spatrick continue;
8714e5dd7070Spatrick // FIXME: If we would typo-correct to an invalid declaration, it's
8715e5dd7070Spatrick // probably best to just suppress all errors from this typo correction.
8716e5dd7070Spatrick ExprResult NE = State.RecoveryHandler ?
8717e5dd7070Spatrick State.RecoveryHandler(SemaRef, E, TC) :
8718e5dd7070Spatrick attemptRecovery(SemaRef, *State.Consumer, TC);
8719e5dd7070Spatrick if (!NE.isInvalid()) {
8720e5dd7070Spatrick // Check whether there may be a second viable correction with the same
8721e5dd7070Spatrick // edit distance; if so, remember this TypoExpr may have an ambiguous
8722e5dd7070Spatrick // correction so it can be more thoroughly vetted later.
8723e5dd7070Spatrick TypoCorrection Next;
8724e5dd7070Spatrick if ((Next = State.Consumer->peekNextCorrection()) &&
8725e5dd7070Spatrick Next.getEditDistance(false) == TC.getEditDistance(false)) {
8726e5dd7070Spatrick AmbiguousTypoExprs.insert(E);
8727e5dd7070Spatrick } else {
8728e5dd7070Spatrick AmbiguousTypoExprs.remove(E);
8729e5dd7070Spatrick }
8730e5dd7070Spatrick assert(!NE.isUnset() &&
8731e5dd7070Spatrick "Typo was transformed into a valid-but-null ExprResult");
8732e5dd7070Spatrick return CacheEntry = NE;
8733e5dd7070Spatrick }
8734e5dd7070Spatrick }
8735e5dd7070Spatrick return CacheEntry = ExprError();
8736e5dd7070Spatrick }
8737e5dd7070Spatrick };
8738e5dd7070Spatrick }
8739e5dd7070Spatrick
8740e5dd7070Spatrick ExprResult
CorrectDelayedTyposInExpr(Expr * E,VarDecl * InitDecl,bool RecoverUncorrectedTypos,llvm::function_ref<ExprResult (Expr *)> Filter)8741e5dd7070Spatrick Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl,
8742ec727ea7Spatrick bool RecoverUncorrectedTypos,
8743e5dd7070Spatrick llvm::function_ref<ExprResult(Expr *)> Filter) {
8744e5dd7070Spatrick // If the current evaluation context indicates there are uncorrected typos
8745e5dd7070Spatrick // and the current expression isn't guaranteed to not have typos, try to
8746e5dd7070Spatrick // resolve any TypoExpr nodes that might be in the expression.
8747e5dd7070Spatrick if (E && !ExprEvalContexts.empty() && ExprEvalContexts.back().NumTypos &&
8748e5dd7070Spatrick (E->isTypeDependent() || E->isValueDependent() ||
8749e5dd7070Spatrick E->isInstantiationDependent())) {
8750e5dd7070Spatrick auto TyposResolved = DelayedTypos.size();
8751e5dd7070Spatrick auto Result = TransformTypos(*this, InitDecl, Filter).Transform(E);
8752e5dd7070Spatrick TyposResolved -= DelayedTypos.size();
8753e5dd7070Spatrick if (Result.isInvalid() || Result.get() != E) {
8754e5dd7070Spatrick ExprEvalContexts.back().NumTypos -= TyposResolved;
8755ec727ea7Spatrick if (Result.isInvalid() && RecoverUncorrectedTypos) {
8756ec727ea7Spatrick struct TyposReplace : TreeTransform<TyposReplace> {
8757ec727ea7Spatrick TyposReplace(Sema &SemaRef) : TreeTransform(SemaRef) {}
8758ec727ea7Spatrick ExprResult TransformTypoExpr(clang::TypoExpr *E) {
8759ec727ea7Spatrick return this->SemaRef.CreateRecoveryExpr(E->getBeginLoc(),
8760ec727ea7Spatrick E->getEndLoc(), {});
8761ec727ea7Spatrick }
8762ec727ea7Spatrick } TT(*this);
8763ec727ea7Spatrick return TT.TransformExpr(E);
8764ec727ea7Spatrick }
8765e5dd7070Spatrick return Result;
8766e5dd7070Spatrick }
8767e5dd7070Spatrick assert(TyposResolved == 0 && "Corrected typo but got same Expr back?");
8768e5dd7070Spatrick }
8769e5dd7070Spatrick return E;
8770e5dd7070Spatrick }
8771e5dd7070Spatrick
ActOnFinishFullExpr(Expr * FE,SourceLocation CC,bool DiscardedValue,bool IsConstexpr,bool IsTemplateArgument)8772e5dd7070Spatrick ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
8773*12c85518Srobert bool DiscardedValue, bool IsConstexpr,
8774*12c85518Srobert bool IsTemplateArgument) {
8775e5dd7070Spatrick ExprResult FullExpr = FE;
8776e5dd7070Spatrick
8777e5dd7070Spatrick if (!FullExpr.get())
8778e5dd7070Spatrick return ExprError();
8779e5dd7070Spatrick
8780*12c85518Srobert if (!IsTemplateArgument && DiagnoseUnexpandedParameterPack(FullExpr.get()))
8781e5dd7070Spatrick return ExprError();
8782e5dd7070Spatrick
8783e5dd7070Spatrick if (DiscardedValue) {
8784e5dd7070Spatrick // Top-level expressions default to 'id' when we're in a debugger.
8785e5dd7070Spatrick if (getLangOpts().DebuggerCastResultToId &&
8786e5dd7070Spatrick FullExpr.get()->getType() == Context.UnknownAnyTy) {
8787e5dd7070Spatrick FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType());
8788e5dd7070Spatrick if (FullExpr.isInvalid())
8789e5dd7070Spatrick return ExprError();
8790e5dd7070Spatrick }
8791e5dd7070Spatrick
8792e5dd7070Spatrick FullExpr = CheckPlaceholderExpr(FullExpr.get());
8793e5dd7070Spatrick if (FullExpr.isInvalid())
8794e5dd7070Spatrick return ExprError();
8795e5dd7070Spatrick
8796e5dd7070Spatrick FullExpr = IgnoredValueConversions(FullExpr.get());
8797e5dd7070Spatrick if (FullExpr.isInvalid())
8798e5dd7070Spatrick return ExprError();
8799e5dd7070Spatrick
8800*12c85518Srobert DiagnoseUnusedExprResult(FullExpr.get(), diag::warn_unused_expr);
8801e5dd7070Spatrick }
8802e5dd7070Spatrick
8803ec727ea7Spatrick FullExpr = CorrectDelayedTyposInExpr(FullExpr.get(), /*InitDecl=*/nullptr,
8804ec727ea7Spatrick /*RecoverUncorrectedTypos=*/true);
8805e5dd7070Spatrick if (FullExpr.isInvalid())
8806e5dd7070Spatrick return ExprError();
8807e5dd7070Spatrick
8808e5dd7070Spatrick CheckCompletedExpr(FullExpr.get(), CC, IsConstexpr);
8809e5dd7070Spatrick
8810e5dd7070Spatrick // At the end of this full expression (which could be a deeply nested
8811e5dd7070Spatrick // lambda), if there is a potential capture within the nested lambda,
8812e5dd7070Spatrick // have the outer capture-able lambda try and capture it.
8813e5dd7070Spatrick // Consider the following code:
8814e5dd7070Spatrick // void f(int, int);
8815e5dd7070Spatrick // void f(const int&, double);
8816e5dd7070Spatrick // void foo() {
8817e5dd7070Spatrick // const int x = 10, y = 20;
8818e5dd7070Spatrick // auto L = [=](auto a) {
8819e5dd7070Spatrick // auto M = [=](auto b) {
8820e5dd7070Spatrick // f(x, b); <-- requires x to be captured by L and M
8821e5dd7070Spatrick // f(y, a); <-- requires y to be captured by L, but not all Ms
8822e5dd7070Spatrick // };
8823e5dd7070Spatrick // };
8824e5dd7070Spatrick // }
8825e5dd7070Spatrick
8826e5dd7070Spatrick // FIXME: Also consider what happens for something like this that involves
8827e5dd7070Spatrick // the gnu-extension statement-expressions or even lambda-init-captures:
8828e5dd7070Spatrick // void f() {
8829e5dd7070Spatrick // const int n = 0;
8830e5dd7070Spatrick // auto L = [&](auto a) {
8831e5dd7070Spatrick // +n + ({ 0; a; });
8832e5dd7070Spatrick // };
8833e5dd7070Spatrick // }
8834e5dd7070Spatrick //
8835e5dd7070Spatrick // Here, we see +n, and then the full-expression 0; ends, so we don't
8836e5dd7070Spatrick // capture n (and instead remove it from our list of potential captures),
8837e5dd7070Spatrick // and then the full-expression +n + ({ 0; }); ends, but it's too late
8838e5dd7070Spatrick // for us to see that we need to capture n after all.
8839e5dd7070Spatrick
8840e5dd7070Spatrick LambdaScopeInfo *const CurrentLSI =
8841e5dd7070Spatrick getCurLambda(/*IgnoreCapturedRegions=*/true);
8842e5dd7070Spatrick // FIXME: PR 17877 showed that getCurLambda() can return a valid pointer
8843e5dd7070Spatrick // even if CurContext is not a lambda call operator. Refer to that Bug Report
8844e5dd7070Spatrick // for an example of the code that might cause this asynchrony.
8845e5dd7070Spatrick // By ensuring we are in the context of a lambda's call operator
8846e5dd7070Spatrick // we can fix the bug (we only need to check whether we need to capture
8847e5dd7070Spatrick // if we are within a lambda's body); but per the comments in that
8848e5dd7070Spatrick // PR, a proper fix would entail :
8849e5dd7070Spatrick // "Alternative suggestion:
8850e5dd7070Spatrick // - Add to Sema an integer holding the smallest (outermost) scope
8851e5dd7070Spatrick // index that we are *lexically* within, and save/restore/set to
8852e5dd7070Spatrick // FunctionScopes.size() in InstantiatingTemplate's
8853e5dd7070Spatrick // constructor/destructor.
8854e5dd7070Spatrick // - Teach the handful of places that iterate over FunctionScopes to
8855e5dd7070Spatrick // stop at the outermost enclosing lexical scope."
8856e5dd7070Spatrick DeclContext *DC = CurContext;
8857e5dd7070Spatrick while (DC && isa<CapturedDecl>(DC))
8858e5dd7070Spatrick DC = DC->getParent();
8859e5dd7070Spatrick const bool IsInLambdaDeclContext = isLambdaCallOperator(DC);
8860e5dd7070Spatrick if (IsInLambdaDeclContext && CurrentLSI &&
8861e5dd7070Spatrick CurrentLSI->hasPotentialCaptures() && !FullExpr.isInvalid())
8862e5dd7070Spatrick CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(FE, CurrentLSI,
8863e5dd7070Spatrick *this);
8864e5dd7070Spatrick return MaybeCreateExprWithCleanups(FullExpr);
8865e5dd7070Spatrick }
8866e5dd7070Spatrick
ActOnFinishFullStmt(Stmt * FullStmt)8867e5dd7070Spatrick StmtResult Sema::ActOnFinishFullStmt(Stmt *FullStmt) {
8868e5dd7070Spatrick if (!FullStmt) return StmtError();
8869e5dd7070Spatrick
8870e5dd7070Spatrick return MaybeCreateStmtWithCleanups(FullStmt);
8871e5dd7070Spatrick }
8872e5dd7070Spatrick
8873e5dd7070Spatrick Sema::IfExistsResult
CheckMicrosoftIfExistsSymbol(Scope * S,CXXScopeSpec & SS,const DeclarationNameInfo & TargetNameInfo)8874e5dd7070Spatrick Sema::CheckMicrosoftIfExistsSymbol(Scope *S,
8875e5dd7070Spatrick CXXScopeSpec &SS,
8876e5dd7070Spatrick const DeclarationNameInfo &TargetNameInfo) {
8877e5dd7070Spatrick DeclarationName TargetName = TargetNameInfo.getName();
8878e5dd7070Spatrick if (!TargetName)
8879e5dd7070Spatrick return IER_DoesNotExist;
8880e5dd7070Spatrick
8881e5dd7070Spatrick // If the name itself is dependent, then the result is dependent.
8882e5dd7070Spatrick if (TargetName.isDependentName())
8883e5dd7070Spatrick return IER_Dependent;
8884e5dd7070Spatrick
8885e5dd7070Spatrick // Do the redeclaration lookup in the current scope.
8886e5dd7070Spatrick LookupResult R(*this, TargetNameInfo, Sema::LookupAnyName,
8887e5dd7070Spatrick Sema::NotForRedeclaration);
8888e5dd7070Spatrick LookupParsedName(R, S, &SS);
8889e5dd7070Spatrick R.suppressDiagnostics();
8890e5dd7070Spatrick
8891e5dd7070Spatrick switch (R.getResultKind()) {
8892e5dd7070Spatrick case LookupResult::Found:
8893e5dd7070Spatrick case LookupResult::FoundOverloaded:
8894e5dd7070Spatrick case LookupResult::FoundUnresolvedValue:
8895e5dd7070Spatrick case LookupResult::Ambiguous:
8896e5dd7070Spatrick return IER_Exists;
8897e5dd7070Spatrick
8898e5dd7070Spatrick case LookupResult::NotFound:
8899e5dd7070Spatrick return IER_DoesNotExist;
8900e5dd7070Spatrick
8901e5dd7070Spatrick case LookupResult::NotFoundInCurrentInstantiation:
8902e5dd7070Spatrick return IER_Dependent;
8903e5dd7070Spatrick }
8904e5dd7070Spatrick
8905e5dd7070Spatrick llvm_unreachable("Invalid LookupResult Kind!");
8906e5dd7070Spatrick }
8907e5dd7070Spatrick
8908e5dd7070Spatrick Sema::IfExistsResult
CheckMicrosoftIfExistsSymbol(Scope * S,SourceLocation KeywordLoc,bool IsIfExists,CXXScopeSpec & SS,UnqualifiedId & Name)8909e5dd7070Spatrick Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
8910e5dd7070Spatrick bool IsIfExists, CXXScopeSpec &SS,
8911e5dd7070Spatrick UnqualifiedId &Name) {
8912e5dd7070Spatrick DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
8913e5dd7070Spatrick
8914e5dd7070Spatrick // Check for an unexpanded parameter pack.
8915e5dd7070Spatrick auto UPPC = IsIfExists ? UPPC_IfExists : UPPC_IfNotExists;
8916e5dd7070Spatrick if (DiagnoseUnexpandedParameterPack(SS, UPPC) ||
8917e5dd7070Spatrick DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC))
8918e5dd7070Spatrick return IER_Error;
8919e5dd7070Spatrick
8920e5dd7070Spatrick return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo);
8921e5dd7070Spatrick }
8922e5dd7070Spatrick
ActOnSimpleRequirement(Expr * E)8923e5dd7070Spatrick concepts::Requirement *Sema::ActOnSimpleRequirement(Expr *E) {
8924e5dd7070Spatrick return BuildExprRequirement(E, /*IsSimple=*/true,
8925e5dd7070Spatrick /*NoexceptLoc=*/SourceLocation(),
8926e5dd7070Spatrick /*ReturnTypeRequirement=*/{});
8927e5dd7070Spatrick }
8928e5dd7070Spatrick
8929e5dd7070Spatrick concepts::Requirement *
ActOnTypeRequirement(SourceLocation TypenameKWLoc,CXXScopeSpec & SS,SourceLocation NameLoc,IdentifierInfo * TypeName,TemplateIdAnnotation * TemplateId)8930e5dd7070Spatrick Sema::ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS,
8931e5dd7070Spatrick SourceLocation NameLoc, IdentifierInfo *TypeName,
8932e5dd7070Spatrick TemplateIdAnnotation *TemplateId) {
8933e5dd7070Spatrick assert(((!TypeName && TemplateId) || (TypeName && !TemplateId)) &&
8934e5dd7070Spatrick "Exactly one of TypeName and TemplateId must be specified.");
8935e5dd7070Spatrick TypeSourceInfo *TSI = nullptr;
8936e5dd7070Spatrick if (TypeName) {
8937e5dd7070Spatrick QualType T = CheckTypenameType(ETK_Typename, TypenameKWLoc,
8938e5dd7070Spatrick SS.getWithLocInContext(Context), *TypeName,
8939*12c85518Srobert NameLoc, &TSI, /*DeducedTSTContext=*/false);
8940e5dd7070Spatrick if (T.isNull())
8941e5dd7070Spatrick return nullptr;
8942e5dd7070Spatrick } else {
8943e5dd7070Spatrick ASTTemplateArgsPtr ArgsPtr(TemplateId->getTemplateArgs(),
8944e5dd7070Spatrick TemplateId->NumArgs);
8945e5dd7070Spatrick TypeResult T = ActOnTypenameType(CurScope, TypenameKWLoc, SS,
8946e5dd7070Spatrick TemplateId->TemplateKWLoc,
8947e5dd7070Spatrick TemplateId->Template, TemplateId->Name,
8948e5dd7070Spatrick TemplateId->TemplateNameLoc,
8949e5dd7070Spatrick TemplateId->LAngleLoc, ArgsPtr,
8950e5dd7070Spatrick TemplateId->RAngleLoc);
8951e5dd7070Spatrick if (T.isInvalid())
8952e5dd7070Spatrick return nullptr;
8953e5dd7070Spatrick if (GetTypeFromParser(T.get(), &TSI).isNull())
8954e5dd7070Spatrick return nullptr;
8955e5dd7070Spatrick }
8956e5dd7070Spatrick return BuildTypeRequirement(TSI);
8957e5dd7070Spatrick }
8958e5dd7070Spatrick
8959e5dd7070Spatrick concepts::Requirement *
ActOnCompoundRequirement(Expr * E,SourceLocation NoexceptLoc)8960e5dd7070Spatrick Sema::ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc) {
8961e5dd7070Spatrick return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc,
8962e5dd7070Spatrick /*ReturnTypeRequirement=*/{});
8963e5dd7070Spatrick }
8964e5dd7070Spatrick
8965e5dd7070Spatrick concepts::Requirement *
ActOnCompoundRequirement(Expr * E,SourceLocation NoexceptLoc,CXXScopeSpec & SS,TemplateIdAnnotation * TypeConstraint,unsigned Depth)8966e5dd7070Spatrick Sema::ActOnCompoundRequirement(
8967e5dd7070Spatrick Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS,
8968e5dd7070Spatrick TemplateIdAnnotation *TypeConstraint, unsigned Depth) {
8969e5dd7070Spatrick // C++2a [expr.prim.req.compound] p1.3.3
8970e5dd7070Spatrick // [..] the expression is deduced against an invented function template
8971e5dd7070Spatrick // F [...] F is a void function template with a single type template
8972e5dd7070Spatrick // parameter T declared with the constrained-parameter. Form a new
8973e5dd7070Spatrick // cv-qualifier-seq cv by taking the union of const and volatile specifiers
8974e5dd7070Spatrick // around the constrained-parameter. F has a single parameter whose
8975e5dd7070Spatrick // type-specifier is cv T followed by the abstract-declarator. [...]
8976e5dd7070Spatrick //
8977e5dd7070Spatrick // The cv part is done in the calling function - we get the concept with
8978e5dd7070Spatrick // arguments and the abstract declarator with the correct CV qualification and
8979e5dd7070Spatrick // have to synthesize T and the single parameter of F.
8980e5dd7070Spatrick auto &II = Context.Idents.get("expr-type");
8981e5dd7070Spatrick auto *TParam = TemplateTypeParmDecl::Create(Context, CurContext,
8982e5dd7070Spatrick SourceLocation(),
8983e5dd7070Spatrick SourceLocation(), Depth,
8984e5dd7070Spatrick /*Index=*/0, &II,
8985e5dd7070Spatrick /*Typename=*/true,
8986e5dd7070Spatrick /*ParameterPack=*/false,
8987e5dd7070Spatrick /*HasTypeConstraint=*/true);
8988e5dd7070Spatrick
8989a9ac8606Spatrick if (BuildTypeConstraint(SS, TypeConstraint, TParam,
8990*12c85518Srobert /*EllipsisLoc=*/SourceLocation(),
8991a9ac8606Spatrick /*AllowUnexpandedPack=*/true))
8992e5dd7070Spatrick // Just produce a requirement with no type requirements.
8993e5dd7070Spatrick return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc, {});
8994e5dd7070Spatrick
8995e5dd7070Spatrick auto *TPL = TemplateParameterList::Create(Context, SourceLocation(),
8996e5dd7070Spatrick SourceLocation(),
8997e5dd7070Spatrick ArrayRef<NamedDecl *>(TParam),
8998e5dd7070Spatrick SourceLocation(),
8999e5dd7070Spatrick /*RequiresClause=*/nullptr);
9000e5dd7070Spatrick return BuildExprRequirement(
9001e5dd7070Spatrick E, /*IsSimple=*/false, NoexceptLoc,
9002e5dd7070Spatrick concepts::ExprRequirement::ReturnTypeRequirement(TPL));
9003e5dd7070Spatrick }
9004e5dd7070Spatrick
9005e5dd7070Spatrick concepts::ExprRequirement *
BuildExprRequirement(Expr * E,bool IsSimple,SourceLocation NoexceptLoc,concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement)9006e5dd7070Spatrick Sema::BuildExprRequirement(
9007e5dd7070Spatrick Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
9008e5dd7070Spatrick concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {
9009e5dd7070Spatrick auto Status = concepts::ExprRequirement::SS_Satisfied;
9010e5dd7070Spatrick ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
9011e5dd7070Spatrick if (E->isInstantiationDependent() || ReturnTypeRequirement.isDependent())
9012e5dd7070Spatrick Status = concepts::ExprRequirement::SS_Dependent;
9013e5dd7070Spatrick else if (NoexceptLoc.isValid() && canThrow(E) == CanThrowResult::CT_Can)
9014e5dd7070Spatrick Status = concepts::ExprRequirement::SS_NoexceptNotMet;
9015e5dd7070Spatrick else if (ReturnTypeRequirement.isSubstitutionFailure())
9016e5dd7070Spatrick Status = concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure;
9017e5dd7070Spatrick else if (ReturnTypeRequirement.isTypeConstraint()) {
9018e5dd7070Spatrick // C++2a [expr.prim.req]p1.3.3
9019e5dd7070Spatrick // The immediately-declared constraint ([temp]) of decltype((E)) shall
9020e5dd7070Spatrick // be satisfied.
9021e5dd7070Spatrick TemplateParameterList *TPL =
9022e5dd7070Spatrick ReturnTypeRequirement.getTypeConstraintTemplateParameterList();
9023e5dd7070Spatrick QualType MatchedType =
9024*12c85518Srobert Context.getReferenceQualifiedType(E).getCanonicalType();
9025e5dd7070Spatrick llvm::SmallVector<TemplateArgument, 1> Args;
9026e5dd7070Spatrick Args.push_back(TemplateArgument(MatchedType));
9027e5dd7070Spatrick
9028*12c85518Srobert auto *Param = cast<TemplateTypeParmDecl>(TPL->getParam(0));
9029*12c85518Srobert
9030*12c85518Srobert TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args);
9031*12c85518Srobert MultiLevelTemplateArgumentList MLTAL(Param, TAL.asArray(),
9032*12c85518Srobert /*Final=*/false);
9033*12c85518Srobert MLTAL.addOuterRetainedLevels(TPL->getDepth());
9034*12c85518Srobert Expr *IDC = Param->getTypeConstraint()->getImmediatelyDeclaredConstraint();
9035*12c85518Srobert ExprResult Constraint = SubstExpr(IDC, MLTAL);
9036*12c85518Srobert if (Constraint.isInvalid()) {
9037*12c85518Srobert Status = concepts::ExprRequirement::SS_ExprSubstitutionFailure;
9038*12c85518Srobert } else {
9039e5dd7070Spatrick SubstitutedConstraintExpr =
9040e5dd7070Spatrick cast<ConceptSpecializationExpr>(Constraint.get());
9041e5dd7070Spatrick if (!SubstitutedConstraintExpr->isSatisfied())
9042e5dd7070Spatrick Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied;
9043e5dd7070Spatrick }
9044*12c85518Srobert }
9045e5dd7070Spatrick return new (Context) concepts::ExprRequirement(E, IsSimple, NoexceptLoc,
9046e5dd7070Spatrick ReturnTypeRequirement, Status,
9047e5dd7070Spatrick SubstitutedConstraintExpr);
9048e5dd7070Spatrick }
9049e5dd7070Spatrick
9050e5dd7070Spatrick concepts::ExprRequirement *
BuildExprRequirement(concepts::Requirement::SubstitutionDiagnostic * ExprSubstitutionDiagnostic,bool IsSimple,SourceLocation NoexceptLoc,concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement)9051e5dd7070Spatrick Sema::BuildExprRequirement(
9052e5dd7070Spatrick concepts::Requirement::SubstitutionDiagnostic *ExprSubstitutionDiagnostic,
9053e5dd7070Spatrick bool IsSimple, SourceLocation NoexceptLoc,
9054e5dd7070Spatrick concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {
9055e5dd7070Spatrick return new (Context) concepts::ExprRequirement(ExprSubstitutionDiagnostic,
9056e5dd7070Spatrick IsSimple, NoexceptLoc,
9057e5dd7070Spatrick ReturnTypeRequirement);
9058e5dd7070Spatrick }
9059e5dd7070Spatrick
9060e5dd7070Spatrick concepts::TypeRequirement *
BuildTypeRequirement(TypeSourceInfo * Type)9061e5dd7070Spatrick Sema::BuildTypeRequirement(TypeSourceInfo *Type) {
9062e5dd7070Spatrick return new (Context) concepts::TypeRequirement(Type);
9063e5dd7070Spatrick }
9064e5dd7070Spatrick
9065e5dd7070Spatrick concepts::TypeRequirement *
BuildTypeRequirement(concepts::Requirement::SubstitutionDiagnostic * SubstDiag)9066e5dd7070Spatrick Sema::BuildTypeRequirement(
9067e5dd7070Spatrick concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
9068e5dd7070Spatrick return new (Context) concepts::TypeRequirement(SubstDiag);
9069e5dd7070Spatrick }
9070e5dd7070Spatrick
ActOnNestedRequirement(Expr * Constraint)9071e5dd7070Spatrick concepts::Requirement *Sema::ActOnNestedRequirement(Expr *Constraint) {
9072e5dd7070Spatrick return BuildNestedRequirement(Constraint);
9073e5dd7070Spatrick }
9074e5dd7070Spatrick
9075e5dd7070Spatrick concepts::NestedRequirement *
BuildNestedRequirement(Expr * Constraint)9076e5dd7070Spatrick Sema::BuildNestedRequirement(Expr *Constraint) {
9077e5dd7070Spatrick ConstraintSatisfaction Satisfaction;
9078e5dd7070Spatrick if (!Constraint->isInstantiationDependent() &&
9079e5dd7070Spatrick CheckConstraintSatisfaction(nullptr, {Constraint}, /*TemplateArgs=*/{},
9080e5dd7070Spatrick Constraint->getSourceRange(), Satisfaction))
9081e5dd7070Spatrick return nullptr;
9082e5dd7070Spatrick return new (Context) concepts::NestedRequirement(Context, Constraint,
9083e5dd7070Spatrick Satisfaction);
9084e5dd7070Spatrick }
9085e5dd7070Spatrick
9086e5dd7070Spatrick concepts::NestedRequirement *
BuildNestedRequirement(StringRef InvalidConstraintEntity,const ASTConstraintSatisfaction & Satisfaction)9087*12c85518Srobert Sema::BuildNestedRequirement(StringRef InvalidConstraintEntity,
9088*12c85518Srobert const ASTConstraintSatisfaction &Satisfaction) {
9089*12c85518Srobert return new (Context) concepts::NestedRequirement(
9090*12c85518Srobert InvalidConstraintEntity,
9091*12c85518Srobert ASTConstraintSatisfaction::Rebuild(Context, Satisfaction));
9092e5dd7070Spatrick }
9093e5dd7070Spatrick
9094e5dd7070Spatrick RequiresExprBodyDecl *
ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,ArrayRef<ParmVarDecl * > LocalParameters,Scope * BodyScope)9095e5dd7070Spatrick Sema::ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,
9096e5dd7070Spatrick ArrayRef<ParmVarDecl *> LocalParameters,
9097e5dd7070Spatrick Scope *BodyScope) {
9098e5dd7070Spatrick assert(BodyScope);
9099e5dd7070Spatrick
9100e5dd7070Spatrick RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(Context, CurContext,
9101e5dd7070Spatrick RequiresKWLoc);
9102e5dd7070Spatrick
9103e5dd7070Spatrick PushDeclContext(BodyScope, Body);
9104e5dd7070Spatrick
9105e5dd7070Spatrick for (ParmVarDecl *Param : LocalParameters) {
9106e5dd7070Spatrick if (Param->hasDefaultArg())
9107e5dd7070Spatrick // C++2a [expr.prim.req] p4
9108e5dd7070Spatrick // [...] A local parameter of a requires-expression shall not have a
9109e5dd7070Spatrick // default argument. [...]
9110e5dd7070Spatrick Diag(Param->getDefaultArgRange().getBegin(),
9111e5dd7070Spatrick diag::err_requires_expr_local_parameter_default_argument);
9112e5dd7070Spatrick // Ignore default argument and move on
9113e5dd7070Spatrick
9114e5dd7070Spatrick Param->setDeclContext(Body);
9115e5dd7070Spatrick // If this has an identifier, add it to the scope stack.
9116e5dd7070Spatrick if (Param->getIdentifier()) {
9117e5dd7070Spatrick CheckShadow(BodyScope, Param);
9118e5dd7070Spatrick PushOnScopeChains(Param, BodyScope);
9119e5dd7070Spatrick }
9120e5dd7070Spatrick }
9121e5dd7070Spatrick return Body;
9122e5dd7070Spatrick }
9123e5dd7070Spatrick
ActOnFinishRequiresExpr()9124e5dd7070Spatrick void Sema::ActOnFinishRequiresExpr() {
9125e5dd7070Spatrick assert(CurContext && "DeclContext imbalance!");
9126e5dd7070Spatrick CurContext = CurContext->getLexicalParent();
9127e5dd7070Spatrick assert(CurContext && "Popped translation unit!");
9128e5dd7070Spatrick }
9129e5dd7070Spatrick
9130e5dd7070Spatrick ExprResult
ActOnRequiresExpr(SourceLocation RequiresKWLoc,RequiresExprBodyDecl * Body,ArrayRef<ParmVarDecl * > LocalParameters,ArrayRef<concepts::Requirement * > Requirements,SourceLocation ClosingBraceLoc)9131e5dd7070Spatrick Sema::ActOnRequiresExpr(SourceLocation RequiresKWLoc,
9132e5dd7070Spatrick RequiresExprBodyDecl *Body,
9133e5dd7070Spatrick ArrayRef<ParmVarDecl *> LocalParameters,
9134e5dd7070Spatrick ArrayRef<concepts::Requirement *> Requirements,
9135e5dd7070Spatrick SourceLocation ClosingBraceLoc) {
9136a9ac8606Spatrick auto *RE = RequiresExpr::Create(Context, RequiresKWLoc, Body, LocalParameters,
9137e5dd7070Spatrick Requirements, ClosingBraceLoc);
9138a9ac8606Spatrick if (DiagnoseUnexpandedParameterPackInRequiresExpr(RE))
9139a9ac8606Spatrick return ExprError();
9140a9ac8606Spatrick return RE;
9141e5dd7070Spatrick }
9142