clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaDeclCXX.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/libclangSema/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/libclangSema/obj/../include/clang/Sema -I /usr/src/gnu/usr.bin/clang/libclangSema/../../../llvm/clang/include -I /usr/src/gnu/usr.bin/clang/libclangSema/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/libclangSema/../include -I /usr/src/gnu/usr.bin/clang/libclangSema/obj -I /usr/src/gnu/usr.bin/clang/libclangSema/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/libclangSema/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/libclangSema/../../../llvm/clang/lib/Sema/SemaDeclCXX.cpp
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "clang/AST/ASTConsumer.h" |
14 | #include "clang/AST/ASTContext.h" |
15 | #include "clang/AST/ASTLambda.h" |
16 | #include "clang/AST/ASTMutationListener.h" |
17 | #include "clang/AST/CXXInheritance.h" |
18 | #include "clang/AST/CharUnits.h" |
19 | #include "clang/AST/ComparisonCategories.h" |
20 | #include "clang/AST/EvaluatedExprVisitor.h" |
21 | #include "clang/AST/ExprCXX.h" |
22 | #include "clang/AST/RecordLayout.h" |
23 | #include "clang/AST/RecursiveASTVisitor.h" |
24 | #include "clang/AST/StmtVisitor.h" |
25 | #include "clang/AST/TypeLoc.h" |
26 | #include "clang/AST/TypeOrdering.h" |
27 | #include "clang/Basic/AttributeCommonInfo.h" |
28 | #include "clang/Basic/PartialDiagnostic.h" |
29 | #include "clang/Basic/TargetInfo.h" |
30 | #include "clang/Lex/LiteralSupport.h" |
31 | #include "clang/Lex/Preprocessor.h" |
32 | #include "clang/Sema/CXXFieldCollector.h" |
33 | #include "clang/Sema/DeclSpec.h" |
34 | #include "clang/Sema/Initialization.h" |
35 | #include "clang/Sema/Lookup.h" |
36 | #include "clang/Sema/ParsedTemplate.h" |
37 | #include "clang/Sema/Scope.h" |
38 | #include "clang/Sema/ScopeInfo.h" |
39 | #include "clang/Sema/SemaInternal.h" |
40 | #include "clang/Sema/Template.h" |
41 | #include "llvm/ADT/ScopeExit.h" |
42 | #include "llvm/ADT/SmallString.h" |
43 | #include "llvm/ADT/STLExtras.h" |
44 | #include "llvm/ADT/StringExtras.h" |
45 | #include <map> |
46 | #include <set> |
47 | |
48 | using namespace clang; |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | namespace { |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | class CheckDefaultArgumentVisitor |
61 | : public ConstStmtVisitor<CheckDefaultArgumentVisitor, bool> { |
62 | Sema &S; |
63 | const Expr *DefaultArg; |
64 | |
65 | public: |
66 | CheckDefaultArgumentVisitor(Sema &S, const Expr *DefaultArg) |
67 | : S(S), DefaultArg(DefaultArg) {} |
68 | |
69 | bool VisitExpr(const Expr *Node); |
70 | bool VisitDeclRefExpr(const DeclRefExpr *DRE); |
71 | bool VisitCXXThisExpr(const CXXThisExpr *ThisE); |
72 | bool VisitLambdaExpr(const LambdaExpr *Lambda); |
73 | bool VisitPseudoObjectExpr(const PseudoObjectExpr *POE); |
74 | }; |
75 | |
76 | |
77 | bool CheckDefaultArgumentVisitor::VisitExpr(const Expr *Node) { |
78 | bool IsInvalid = false; |
79 | for (const Stmt *SubStmt : Node->children()) |
80 | IsInvalid |= Visit(SubStmt); |
81 | return IsInvalid; |
82 | } |
83 | |
84 | |
85 | |
86 | |
87 | bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(const DeclRefExpr *DRE) { |
88 | const NamedDecl *Decl = DRE->getDecl(); |
89 | if (const auto *Param = dyn_cast<ParmVarDecl>(Decl)) { |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | if (DRE->isNonOdrUse() != NOUR_Unevaluated) |
99 | return S.Diag(DRE->getBeginLoc(), |
100 | diag::err_param_default_argument_references_param) |
101 | << Param->getDeclName() << DefaultArg->getSourceRange(); |
102 | } else if (const auto *VDecl = dyn_cast<VarDecl>(Decl)) { |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | if (VDecl->isLocalVarDecl() && !DRE->isNonOdrUse()) |
115 | return S.Diag(DRE->getBeginLoc(), |
116 | diag::err_param_default_argument_references_local) |
117 | << VDecl->getDeclName() << DefaultArg->getSourceRange(); |
118 | } |
119 | |
120 | return false; |
121 | } |
122 | |
123 | |
124 | bool CheckDefaultArgumentVisitor::VisitCXXThisExpr(const CXXThisExpr *ThisE) { |
125 | |
126 | |
127 | |
128 | return S.Diag(ThisE->getBeginLoc(), |
129 | diag::err_param_default_argument_references_this) |
130 | << ThisE->getSourceRange(); |
131 | } |
132 | |
133 | bool CheckDefaultArgumentVisitor::VisitPseudoObjectExpr( |
134 | const PseudoObjectExpr *POE) { |
135 | bool Invalid = false; |
136 | for (const Expr *E : POE->semantics()) { |
137 | |
138 | if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E)) { |
139 | E = OVE->getSourceExpr(); |
140 | assert(E && "pseudo-object binding without source expression?"); |
141 | } |
142 | |
143 | Invalid |= Visit(E); |
144 | } |
145 | return Invalid; |
146 | } |
147 | |
148 | bool CheckDefaultArgumentVisitor::VisitLambdaExpr(const LambdaExpr *Lambda) { |
149 | |
150 | |
151 | |
152 | if (Lambda->capture_begin() == Lambda->capture_end()) |
153 | return false; |
154 | |
155 | return S.Diag(Lambda->getBeginLoc(), diag::err_lambda_capture_default_arg); |
156 | } |
157 | } |
158 | |
159 | void |
160 | Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc, |
161 | const CXXMethodDecl *Method) { |
162 | |
163 | if (!Method || ComputedEST == EST_MSAny) |
164 | return; |
165 | |
166 | const FunctionProtoType *Proto |
167 | = Method->getType()->getAs<FunctionProtoType>(); |
168 | Proto = Self->ResolveExceptionSpec(CallLoc, Proto); |
169 | if (!Proto) |
170 | return; |
171 | |
172 | ExceptionSpecificationType EST = Proto->getExceptionSpecType(); |
173 | |
174 | |
175 | if (ComputedEST == EST_None) |
176 | return; |
177 | |
178 | if (EST == EST_None && Method->hasAttr<NoThrowAttr>()) |
179 | EST = EST_BasicNoexcept; |
180 | |
181 | switch (EST) { |
182 | case EST_Unparsed: |
183 | case EST_Uninstantiated: |
184 | case EST_Unevaluated: |
185 | llvm_unreachable("should not see unresolved exception specs here"); |
186 | |
187 | |
188 | case EST_MSAny: |
189 | case EST_None: |
190 | |
191 | |
192 | ClearExceptions(); |
193 | ComputedEST = EST; |
194 | return; |
195 | case EST_NoexceptFalse: |
196 | ClearExceptions(); |
197 | ComputedEST = EST_None; |
198 | return; |
199 | |
200 | |
201 | |
202 | case EST_BasicNoexcept: |
203 | case EST_NoexceptTrue: |
204 | case EST_NoThrow: |
205 | return; |
206 | |
207 | |
208 | case EST_DynamicNone: |
209 | if (ComputedEST == EST_BasicNoexcept) |
210 | ComputedEST = EST_DynamicNone; |
211 | return; |
212 | case EST_DependentNoexcept: |
213 | llvm_unreachable( |
214 | "should not generate implicit declarations for dependent cases"); |
215 | case EST_Dynamic: |
216 | break; |
217 | } |
218 | assert(EST == EST_Dynamic && "EST case not considered earlier."); |
219 | assert(ComputedEST != EST_None && |
220 | "Shouldn't collect exceptions when throw-all is guaranteed."); |
221 | ComputedEST = EST_Dynamic; |
222 | |
223 | for (const auto &E : Proto->exceptions()) |
224 | if (ExceptionsSeen.insert(Self->Context.getCanonicalType(E)).second) |
225 | Exceptions.push_back(E); |
226 | } |
227 | |
228 | void Sema::ImplicitExceptionSpecification::CalledStmt(Stmt *S) { |
229 | if (!S || ComputedEST == EST_MSAny) |
230 | return; |
231 | |
232 | |
233 | |
234 | |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | |
241 | |
242 | |
243 | |
244 | |
245 | |
246 | |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | if (Self->canThrow(S)) |
254 | ComputedEST = EST_None; |
255 | } |
256 | |
257 | ExprResult Sema::ConvertParamDefaultArgument(ParmVarDecl *Param, Expr *Arg, |
258 | SourceLocation EqualLoc) { |
259 | if (RequireCompleteType(Param->getLocation(), Param->getType(), |
260 | diag::err_typecheck_decl_incomplete_type)) |
261 | return true; |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, |
270 | Param); |
271 | InitializationKind Kind = InitializationKind::CreateCopy(Param->getLocation(), |
272 | EqualLoc); |
273 | InitializationSequence InitSeq(*this, Entity, Kind, Arg); |
274 | ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Arg); |
275 | if (Result.isInvalid()) |
276 | return true; |
277 | Arg = Result.getAs<Expr>(); |
278 | |
279 | CheckCompletedExpr(Arg, EqualLoc); |
280 | Arg = MaybeCreateExprWithCleanups(Arg); |
281 | |
282 | return Arg; |
283 | } |
284 | |
285 | void Sema::SetParamDefaultArgument(ParmVarDecl *Param, Expr *Arg, |
286 | SourceLocation EqualLoc) { |
287 | |
288 | Param->setDefaultArg(Arg); |
289 | |
290 | |
291 | |
292 | UnparsedDefaultArgInstantiationsMap::iterator InstPos |
293 | = UnparsedDefaultArgInstantiations.find(Param); |
294 | if (InstPos != UnparsedDefaultArgInstantiations.end()) { |
295 | for (unsigned I = 0, N = InstPos->second.size(); I != N; ++I) |
296 | InstPos->second[I]->setUninstantiatedDefaultArg(Arg); |
297 | |
298 | |
299 | UnparsedDefaultArgInstantiations.erase(InstPos); |
300 | } |
301 | } |
302 | |
303 | |
304 | |
305 | |
306 | void |
307 | Sema::ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, |
308 | Expr *DefaultArg) { |
309 | if (!param || !DefaultArg) |
310 | return; |
311 | |
312 | ParmVarDecl *Param = cast<ParmVarDecl>(param); |
313 | UnparsedDefaultArgLocs.erase(Param); |
314 | |
315 | auto Fail = [&] { |
316 | Param->setInvalidDecl(); |
317 | Param->setDefaultArg(new (Context) OpaqueValueExpr( |
318 | EqualLoc, Param->getType().getNonReferenceType(), VK_PRValue)); |
319 | }; |
320 | |
321 | |
322 | if (!getLangOpts().CPlusPlus) { |
323 | Diag(EqualLoc, diag::err_param_default_argument) |
324 | << DefaultArg->getSourceRange(); |
325 | return Fail(); |
326 | } |
327 | |
328 | |
329 | if (DiagnoseUnexpandedParameterPack(DefaultArg, UPPC_DefaultArgument)) { |
330 | return Fail(); |
331 | } |
332 | |
333 | |
334 | |
335 | |
336 | if (Param->isParameterPack()) { |
337 | Diag(EqualLoc, diag::err_param_default_argument_on_parameter_pack) |
338 | << DefaultArg->getSourceRange(); |
339 | |
340 | Param->setDefaultArg(nullptr); |
341 | return; |
342 | } |
343 | |
344 | ExprResult Result = ConvertParamDefaultArgument(Param, DefaultArg, EqualLoc); |
345 | if (Result.isInvalid()) |
346 | return Fail(); |
347 | |
348 | DefaultArg = Result.getAs<Expr>(); |
349 | |
350 | |
351 | CheckDefaultArgumentVisitor DefaultArgChecker(*this, DefaultArg); |
352 | if (DefaultArgChecker.Visit(DefaultArg)) |
353 | return Fail(); |
354 | |
355 | SetParamDefaultArgument(Param, DefaultArg, EqualLoc); |
356 | } |
357 | |
358 | |
359 | |
360 | |
361 | |
362 | void Sema::ActOnParamUnparsedDefaultArgument(Decl *param, |
363 | SourceLocation EqualLoc, |
364 | SourceLocation ArgLoc) { |
365 | if (!param) |
366 | return; |
367 | |
368 | ParmVarDecl *Param = cast<ParmVarDecl>(param); |
369 | Param->setUnparsedDefaultArg(); |
370 | UnparsedDefaultArgLocs[Param] = ArgLoc; |
371 | } |
372 | |
373 | |
374 | |
375 | void Sema::ActOnParamDefaultArgumentError(Decl *param, |
376 | SourceLocation EqualLoc) { |
377 | if (!param) |
378 | return; |
379 | |
380 | ParmVarDecl *Param = cast<ParmVarDecl>(param); |
381 | Param->setInvalidDecl(); |
382 | UnparsedDefaultArgLocs.erase(Param); |
383 | Param->setDefaultArg(new (Context) OpaqueValueExpr( |
384 | EqualLoc, Param->getType().getNonReferenceType(), VK_PRValue)); |
385 | } |
386 | |
387 | |
388 | |
389 | |
390 | |
391 | |
392 | void Sema::CheckExtraCXXDefaultArguments(Declarator &D) { |
393 | |
394 | |
395 | |
396 | |
397 | |
398 | |
399 | |
400 | bool MightBeFunction = D.isFunctionDeclarationContext(); |
401 | for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { |
402 | DeclaratorChunk &chunk = D.getTypeObject(i); |
403 | if (chunk.Kind == DeclaratorChunk::Function) { |
404 | if (MightBeFunction) { |
405 | |
406 | |
407 | |
408 | MightBeFunction = false; |
409 | continue; |
410 | } |
411 | for (unsigned argIdx = 0, e = chunk.Fun.NumParams; argIdx != e; |
412 | ++argIdx) { |
413 | ParmVarDecl *Param = cast<ParmVarDecl>(chunk.Fun.Params[argIdx].Param); |
414 | if (Param->hasUnparsedDefaultArg()) { |
415 | std::unique_ptr<CachedTokens> Toks = |
416 | std::move(chunk.Fun.Params[argIdx].DefaultArgTokens); |
417 | SourceRange SR; |
418 | if (Toks->size() > 1) |
419 | SR = SourceRange((*Toks)[1].getLocation(), |
420 | Toks->back().getLocation()); |
421 | else |
422 | SR = UnparsedDefaultArgLocs[Param]; |
423 | Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc) |
424 | << SR; |
425 | } else if (Param->getDefaultArg()) { |
426 | Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc) |
427 | << Param->getDefaultArg()->getSourceRange(); |
428 | Param->setDefaultArg(nullptr); |
429 | } |
430 | } |
431 | } else if (chunk.Kind != DeclaratorChunk::Paren) { |
432 | MightBeFunction = false; |
433 | } |
434 | } |
435 | } |
436 | |
437 | static bool functionDeclHasDefaultArgument(const FunctionDecl *FD) { |
438 | return std::any_of(FD->param_begin(), FD->param_end(), [](ParmVarDecl *P) { |
439 | return P->hasDefaultArg() && !P->hasInheritedDefaultArg(); |
440 | }); |
441 | } |
442 | |
443 | |
444 | |
445 | |
446 | |
447 | bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, |
448 | Scope *S) { |
449 | bool Invalid = false; |
450 | |
451 | |
452 | |
453 | |
454 | DeclContext *ScopeDC = New->isLocalExternDecl() |
455 | ? New->getLexicalDeclContext() |
456 | : New->getDeclContext(); |
457 | |
458 | |
459 | FunctionDecl *PrevForDefaultArgs = Old; |
460 | for (; PrevForDefaultArgs; |
461 | |
462 | |
463 | PrevForDefaultArgs = New->isLocalExternDecl() |
464 | ? nullptr |
465 | : PrevForDefaultArgs->getPreviousDecl()) { |
466 | |
467 | if (!LookupResult::isVisible(*this, PrevForDefaultArgs)) |
468 | continue; |
469 | |
470 | if (S && !isDeclInScope(PrevForDefaultArgs, ScopeDC, S) && |
471 | !New->isCXXClassMember()) { |
472 | |
473 | |
474 | |
475 | continue; |
476 | } |
477 | |
478 | if (PrevForDefaultArgs->isLocalExternDecl() != New->isLocalExternDecl()) { |
479 | |
480 | |
481 | |
482 | |
483 | continue; |
484 | } |
485 | |
486 | |
487 | break; |
488 | } |
489 | |
490 | |
491 | |
492 | |
493 | |
494 | |
495 | |
496 | |
497 | |
498 | |
499 | |
500 | |
501 | |
502 | |
503 | |
504 | |
505 | |
506 | |
507 | |
508 | for (unsigned p = 0, NumParams = PrevForDefaultArgs |
509 | ? PrevForDefaultArgs->getNumParams() |
510 | : 0; |
511 | p < NumParams; ++p) { |
512 | ParmVarDecl *OldParam = PrevForDefaultArgs->getParamDecl(p); |
513 | ParmVarDecl *NewParam = New->getParamDecl(p); |
514 | |
515 | bool OldParamHasDfl = OldParam ? OldParam->hasDefaultArg() : false; |
516 | bool NewParamHasDfl = NewParam->hasDefaultArg(); |
517 | |
518 | if (OldParamHasDfl && NewParamHasDfl) { |
519 | unsigned DiagDefaultParamID = |
520 | diag::err_param_default_argument_redefinition; |
521 | |
522 | |
523 | |
524 | Invalid = true; |
525 | if (getLangOpts().MicrosoftExt) { |
526 | CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(New); |
527 | if (MD && MD->getParent()->getDescribedClassTemplate()) { |
528 | |
529 | NewParam->setHasInheritedDefaultArg(); |
530 | if (OldParam->hasUninstantiatedDefaultArg()) |
531 | NewParam->setUninstantiatedDefaultArg( |
532 | OldParam->getUninstantiatedDefaultArg()); |
533 | else |
534 | NewParam->setDefaultArg(OldParam->getInit()); |
535 | DiagDefaultParamID = diag::ext_param_default_argument_redefinition; |
536 | Invalid = false; |
537 | } |
538 | } |
539 | |
540 | |
541 | |
542 | |
543 | |
544 | |
545 | |
546 | |
547 | |
548 | Diag(NewParam->getLocation(), DiagDefaultParamID) |
549 | << NewParam->getDefaultArgRange(); |
550 | |
551 | |
552 | |
553 | for (auto Older = PrevForDefaultArgs; |
554 | OldParam->hasInheritedDefaultArg(); ) { |
555 | Older = Older->getPreviousDecl(); |
556 | OldParam = Older->getParamDecl(p); |
557 | } |
558 | |
559 | Diag(OldParam->getLocation(), diag::note_previous_definition) |
560 | << OldParam->getDefaultArgRange(); |
561 | } else if (OldParamHasDfl) { |
562 | |
563 | |
564 | |
565 | |
566 | if (New->getFriendObjectKind() == Decl::FOK_None || |
567 | !New->getLexicalDeclContext()->isDependentContext()) { |
568 | |
569 | |
570 | NewParam->setHasInheritedDefaultArg(); |
571 | if (OldParam->hasUnparsedDefaultArg()) |
572 | NewParam->setUnparsedDefaultArg(); |
573 | else if (OldParam->hasUninstantiatedDefaultArg()) |
574 | NewParam->setUninstantiatedDefaultArg( |
575 | OldParam->getUninstantiatedDefaultArg()); |
576 | else |
577 | NewParam->setDefaultArg(OldParam->getInit()); |
578 | } |
579 | } else if (NewParamHasDfl) { |
580 | if (New->getDescribedFunctionTemplate()) { |
581 | |
582 | Diag(NewParam->getLocation(), |
583 | diag::err_param_default_argument_template_redecl) |
584 | << NewParam->getDefaultArgRange(); |
585 | Diag(PrevForDefaultArgs->getLocation(), |
586 | diag::note_template_prev_declaration) |
587 | << false; |
588 | } else if (New->getTemplateSpecializationKind() |
589 | != TSK_ImplicitInstantiation && |
590 | New->getTemplateSpecializationKind() != TSK_Undeclared) { |
591 | |
592 | |
593 | |
594 | |
595 | |
596 | |
597 | |
598 | |
599 | |
600 | Diag(NewParam->getLocation(), diag::err_template_spec_default_arg) |
601 | << (New->getTemplateSpecializationKind() ==TSK_ExplicitSpecialization) |
602 | << New->getDeclName() |
603 | << NewParam->getDefaultArgRange(); |
604 | } else if (New->getDeclContext()->isDependentContext()) { |
605 | |
606 | |
607 | |
608 | |
609 | |
610 | |
611 | |
612 | |
613 | |
614 | int WhichKind = 2; |
615 | if (CXXRecordDecl *Record |
616 | = dyn_cast<CXXRecordDecl>(New->getDeclContext())) { |
617 | if (Record->getDescribedClassTemplate()) |
618 | WhichKind = 0; |
619 | else if (isa<ClassTemplatePartialSpecializationDecl>(Record)) |
620 | WhichKind = 1; |
621 | else |
622 | WhichKind = 2; |
623 | } |
624 | |
625 | Diag(NewParam->getLocation(), |
626 | diag::err_param_default_argument_member_template_redecl) |
627 | << WhichKind |
628 | << NewParam->getDefaultArgRange(); |
629 | } |
630 | } |
631 | } |
632 | |
633 | |
634 | |
635 | |
636 | if (isa<CXXConstructorDecl>(New) && |
637 | New->getMinRequiredArguments() < Old->getMinRequiredArguments()) { |
638 | CXXSpecialMember NewSM = getSpecialMember(cast<CXXMethodDecl>(New)), |
639 | OldSM = getSpecialMember(cast<CXXMethodDecl>(Old)); |
640 | if (NewSM != OldSM) { |
641 | ParmVarDecl *NewParam = New->getParamDecl(New->getMinRequiredArguments()); |
642 | assert(NewParam->hasDefaultArg()); |
643 | Diag(NewParam->getLocation(), diag::err_default_arg_makes_ctor_special) |
644 | << NewParam->getDefaultArgRange() << NewSM; |
645 | Diag(Old->getLocation(), diag::note_previous_declaration); |
646 | } |
647 | } |
648 | |
649 | const FunctionDecl *Def; |
650 | |
651 | |
652 | |
653 | if (New->getConstexprKind() != Old->getConstexprKind()) { |
654 | Diag(New->getLocation(), diag::err_constexpr_redecl_mismatch) |
655 | << New << static_cast<int>(New->getConstexprKind()) |
656 | << static_cast<int>(Old->getConstexprKind()); |
657 | Diag(Old->getLocation(), diag::note_previous_declaration); |
658 | Invalid = true; |
659 | } else if (!Old->getMostRecentDecl()->isInlined() && New->isInlined() && |
660 | Old->isDefined(Def) && |
661 | |
662 | |
663 | |
664 | (New->isInlineSpecified() || |
665 | New->getFriendObjectKind() == Decl::FOK_None)) { |
666 | |
667 | |
668 | |
669 | Diag(New->getLocation(), diag::err_inline_decl_follows_def) << New; |
670 | Diag(Def->getLocation(), diag::note_previous_definition); |
671 | Invalid = true; |
672 | } |
673 | |
674 | |
675 | |
676 | |
677 | |
678 | if (isa<CXXDeductionGuideDecl>(New) && |
679 | !New->isFunctionTemplateSpecialization() && isVisible(Old)) { |
680 | Diag(New->getLocation(), diag::err_deduction_guide_redeclared); |
681 | Diag(Old->getLocation(), diag::note_previous_declaration); |
682 | } |
683 | |
684 | |
685 | |
686 | |
687 | |
688 | if (Old->getFriendObjectKind() == Decl::FOK_Undeclared && |
689 | functionDeclHasDefaultArgument(Old)) { |
690 | Diag(New->getLocation(), diag::err_friend_decl_with_def_arg_redeclared); |
691 | Diag(Old->getLocation(), diag::note_previous_declaration); |
692 | Invalid = true; |
693 | } |
694 | |
695 | |
696 | |
697 | |
698 | |
699 | |
700 | |
701 | const FunctionDecl *OldDefinition = nullptr; |
702 | if (New->isThisDeclarationInstantiatedFromAFriendDefinition() && |
703 | Old->isDefined(OldDefinition, true)) |
704 | CheckForFunctionRedefinition(New, OldDefinition); |
705 | |
706 | return Invalid; |
707 | } |
708 | |
709 | NamedDecl * |
710 | Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D, |
711 | MultiTemplateParamsArg TemplateParamLists) { |
712 | assert(D.isDecompositionDeclarator()); |
713 | const DecompositionDeclarator &Decomp = D.getDecompositionDeclarator(); |
714 | |
715 | |
716 | |
717 | |
718 | if (!D.mayHaveDecompositionDeclarator()) { |
719 | Diag(Decomp.getLSquareLoc(), diag::err_decomp_decl_context) |
720 | << Decomp.getSourceRange(); |
721 | return nullptr; |
722 | } |
723 | |
724 | if (!TemplateParamLists.empty()) { |
725 | |
726 | |
727 | Diag(TemplateParamLists.front()->getTemplateLoc(), |
728 | diag::err_decomp_decl_template); |
729 | return nullptr; |
730 | } |
731 | |
732 | Diag(Decomp.getLSquareLoc(), |
733 | !getLangOpts().CPlusPlus17 |
734 | ? diag::ext_decomp_decl |
735 | : D.getContext() == DeclaratorContext::Condition |
736 | ? diag::ext_decomp_decl_cond |
737 | : diag::warn_cxx14_compat_decomp_decl) |
738 | << Decomp.getSourceRange(); |
739 | |
740 | |
741 | DeclContext *const DC = CurContext; |
742 | |
743 | |
744 | |
745 | |
746 | |
747 | |
748 | |
749 | auto &DS = D.getDeclSpec(); |
750 | { |
751 | SmallVector<StringRef, 8> BadSpecifiers; |
752 | SmallVector<SourceLocation, 8> BadSpecifierLocs; |
753 | SmallVector<StringRef, 8> CPlusPlus20Specifiers; |
754 | SmallVector<SourceLocation, 8> CPlusPlus20SpecifierLocs; |
755 | if (auto SCS = DS.getStorageClassSpec()) { |
756 | if (SCS == DeclSpec::SCS_static) { |
757 | CPlusPlus20Specifiers.push_back(DeclSpec::getSpecifierName(SCS)); |
758 | CPlusPlus20SpecifierLocs.push_back(DS.getStorageClassSpecLoc()); |
759 | } else { |
760 | BadSpecifiers.push_back(DeclSpec::getSpecifierName(SCS)); |
761 | BadSpecifierLocs.push_back(DS.getStorageClassSpecLoc()); |
762 | } |
763 | } |
764 | if (auto TSCS = DS.getThreadStorageClassSpec()) { |
765 | CPlusPlus20Specifiers.push_back(DeclSpec::getSpecifierName(TSCS)); |
766 | CPlusPlus20SpecifierLocs.push_back(DS.getThreadStorageClassSpecLoc()); |
767 | } |
768 | if (DS.hasConstexprSpecifier()) { |
769 | BadSpecifiers.push_back( |
770 | DeclSpec::getSpecifierName(DS.getConstexprSpecifier())); |
771 | BadSpecifierLocs.push_back(DS.getConstexprSpecLoc()); |
772 | } |
773 | if (DS.isInlineSpecified()) { |
774 | BadSpecifiers.push_back("inline"); |
775 | BadSpecifierLocs.push_back(DS.getInlineSpecLoc()); |
776 | } |
777 | if (!BadSpecifiers.empty()) { |
778 | auto &&Err = Diag(BadSpecifierLocs.front(), diag::err_decomp_decl_spec); |
779 | Err << (int)BadSpecifiers.size() |
780 | << llvm::join(BadSpecifiers.begin(), BadSpecifiers.end(), " "); |
781 | |
782 | |
783 | for (auto Loc : BadSpecifierLocs) |
784 | Err << SourceRange(Loc, Loc); |
785 | } else if (!CPlusPlus20Specifiers.empty()) { |
786 | auto &&Warn = Diag(CPlusPlus20SpecifierLocs.front(), |
787 | getLangOpts().CPlusPlus20 |
788 | ? diag::warn_cxx17_compat_decomp_decl_spec |
789 | : diag::ext_decomp_decl_spec); |
790 | Warn << (int)CPlusPlus20Specifiers.size() |
791 | << llvm::join(CPlusPlus20Specifiers.begin(), |
792 | CPlusPlus20Specifiers.end(), " "); |
793 | for (auto Loc : CPlusPlus20SpecifierLocs) |
794 | Warn << SourceRange(Loc, Loc); |
795 | } |
796 | |
797 | if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) |
798 | return nullptr; |
799 | } |
800 | |
801 | |
802 | |
803 | if ((DS.getTypeQualifiers() & DeclSpec::TQ_volatile) && |
804 | getLangOpts().CPlusPlus20) |
805 | Diag(DS.getVolatileSpecLoc(), |
806 | diag::warn_deprecated_volatile_structured_binding); |
807 | |
808 | TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); |
809 | QualType R = TInfo->getType(); |
810 | |
811 | if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo, |
812 | UPPC_DeclarationType)) |
813 | D.setInvalidType(); |
814 | |
815 | |
816 | |
817 | |
818 | if (DS.getTypeSpecType() != DeclSpec::TST_auto || |
819 | D.hasGroupingParens() || D.getNumTypeObjects() > 1 || |
820 | (D.getNumTypeObjects() == 1 && |
821 | D.getTypeObject(0).Kind != DeclaratorChunk::Reference)) { |
822 | Diag(Decomp.getLSquareLoc(), |
823 | (D.hasGroupingParens() || |
824 | (D.getNumTypeObjects() && |
825 | D.getTypeObject(0).Kind == DeclaratorChunk::Paren)) |
826 | ? diag::err_decomp_decl_parens |
827 | : diag::err_decomp_decl_type) |
828 | << R; |
829 | |
830 | |
831 | |
832 | |
833 | if (R->isFunctionType()) |
834 | D.setInvalidType(); |
835 | } |
836 | |
837 | |
838 | SmallVector<BindingDecl*, 8> Bindings; |
839 | |
840 | |
841 | for (auto &B : D.getDecompositionDeclarator().bindings()) { |
842 | |
843 | DeclarationNameInfo NameInfo(B.Name, B.NameLoc); |
844 | LookupResult Previous(*this, NameInfo, LookupOrdinaryName, |
845 | ForVisibleRedeclaration); |
846 | LookupName(Previous, S, |
847 | DC->getRedeclContext()->isTranslationUnit()); |
848 | |
849 | |
850 | if (Previous.isSingleResult() && |
851 | Previous.getFoundDecl()->isTemplateParameter()) { |
852 | DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), |
853 | Previous.getFoundDecl()); |
854 | Previous.clear(); |
855 | } |
856 | |
857 | auto *BD = BindingDecl::Create(Context, DC, B.NameLoc, B.Name); |
858 | |
859 | |
860 | NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty() |
861 | ? getShadowedDeclaration(BD, Previous) |
862 | : nullptr; |
863 | |
864 | bool ConsiderLinkage = DC->isFunctionOrMethod() && |
865 | DS.getStorageClassSpec() == DeclSpec::SCS_extern; |
866 | FilterLookupForScope(Previous, DC, S, ConsiderLinkage, |
867 | false); |
868 | |
869 | if (!Previous.empty()) { |
870 | auto *Old = Previous.getRepresentativeDecl(); |
871 | Diag(B.NameLoc, diag::err_redefinition) << B.Name; |
872 | Diag(Old->getLocation(), diag::note_previous_definition); |
873 | } else if (ShadowedDecl && !D.isRedeclaration()) { |
874 | CheckShadow(BD, ShadowedDecl, Previous); |
875 | } |
876 | PushOnScopeChains(BD, S, true); |
877 | Bindings.push_back(BD); |
878 | ParsingInitForAutoVars.insert(BD); |
879 | } |
880 | |
881 | |
882 | |
883 | DeclarationNameInfo NameInfo((IdentifierInfo *)nullptr, |
884 | Decomp.getLSquareLoc()); |
885 | LookupResult Previous(*this, NameInfo, LookupOrdinaryName, |
886 | ForVisibleRedeclaration); |
887 | |
888 | |
889 | bool AddToScope = true; |
890 | NamedDecl *New = |
891 | ActOnVariableDeclarator(S, D, DC, TInfo, Previous, |
892 | MultiTemplateParamsArg(), AddToScope, Bindings); |
893 | if (AddToScope) { |
894 | S->AddDecl(New); |
895 | CurContext->addHiddenDecl(New); |
896 | } |
897 | |
898 | if (isInOpenMPDeclareTargetContext()) |
899 | checkDeclIsAllowedInOpenMPTarget(nullptr, New); |
900 | |
901 | return New; |
902 | } |
903 | |
904 | static bool checkSimpleDecomposition( |
905 | Sema &S, ArrayRef<BindingDecl *> Bindings, ValueDecl *Src, |
906 | QualType DecompType, const llvm::APSInt &NumElems, QualType ElemType, |
907 | llvm::function_ref<ExprResult(SourceLocation, Expr *, unsigned)> GetInit) { |
908 | if ((int64_t)Bindings.size() != NumElems) { |
909 | S.Diag(Src->getLocation(), diag::err_decomp_decl_wrong_number_bindings) |
910 | << DecompType << (unsigned)Bindings.size() |
911 | << (unsigned)NumElems.getLimitedValue(UINT_MAX) |
912 | << toString(NumElems, 10) << (NumElems < Bindings.size()); |
913 | return true; |
914 | } |
915 | |
916 | unsigned I = 0; |
917 | for (auto *B : Bindings) { |
918 | SourceLocation Loc = B->getLocation(); |
919 | ExprResult E = S.BuildDeclRefExpr(Src, DecompType, VK_LValue, Loc); |
920 | if (E.isInvalid()) |
921 | return true; |
922 | E = GetInit(Loc, E.get(), I++); |
923 | if (E.isInvalid()) |
924 | return true; |
925 | B->setBinding(ElemType, E.get()); |
926 | } |
927 | |
928 | return false; |
929 | } |
930 | |
931 | static bool checkArrayLikeDecomposition(Sema &S, |
932 | ArrayRef<BindingDecl *> Bindings, |
933 | ValueDecl *Src, QualType DecompType, |
934 | const llvm::APSInt &NumElems, |
935 | QualType ElemType) { |
936 | return checkSimpleDecomposition( |
937 | S, Bindings, Src, DecompType, NumElems, ElemType, |
938 | [&](SourceLocation Loc, Expr *Base, unsigned I) -> ExprResult { |
939 | ExprResult E = S.ActOnIntegerConstant(Loc, I); |
940 | if (E.isInvalid()) |
941 | return ExprError(); |
942 | return S.CreateBuiltinArraySubscriptExpr(Base, Loc, E.get(), Loc); |
943 | }); |
944 | } |
945 | |
946 | static bool checkArrayDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings, |
947 | ValueDecl *Src, QualType DecompType, |
948 | const ConstantArrayType *CAT) { |
949 | return checkArrayLikeDecomposition(S, Bindings, Src, DecompType, |
950 | llvm::APSInt(CAT->getSize()), |
951 | CAT->getElementType()); |
952 | } |
953 | |
954 | static bool checkVectorDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings, |
955 | ValueDecl *Src, QualType DecompType, |
956 | const VectorType *VT) { |
957 | return checkArrayLikeDecomposition( |
958 | S, Bindings, Src, DecompType, llvm::APSInt::get(VT->getNumElements()), |
959 | S.Context.getQualifiedType(VT->getElementType(), |
960 | DecompType.getQualifiers())); |
961 | } |
962 | |
963 | static bool checkComplexDecomposition(Sema &S, |
964 | ArrayRef<BindingDecl *> Bindings, |
965 | ValueDecl *Src, QualType DecompType, |
966 | const ComplexType *CT) { |
967 | return checkSimpleDecomposition( |
968 | S, Bindings, Src, DecompType, llvm::APSInt::get(2), |
969 | S.Context.getQualifiedType(CT->getElementType(), |
970 | DecompType.getQualifiers()), |
971 | [&](SourceLocation Loc, Expr *Base, unsigned I) -> ExprResult { |
972 | return S.CreateBuiltinUnaryOp(Loc, I ? UO_Imag : UO_Real, Base); |
973 | }); |
974 | } |
975 | |
976 | static std::string printTemplateArgs(const PrintingPolicy &PrintingPolicy, |
977 | TemplateArgumentListInfo &Args, |
978 | const TemplateParameterList *Params) { |
979 | SmallString<128> SS; |
980 | llvm::raw_svector_ostream OS(SS); |
981 | bool First = true; |
982 | unsigned I = 0; |
983 | for (auto &Arg : Args.arguments()) { |
984 | if (!First) |
985 | OS << ", "; |
986 | Arg.getArgument().print( |
987 | PrintingPolicy, OS, |
988 | TemplateParameterList::shouldIncludeTypeForArgument(Params, I)); |
989 | First = false; |
990 | I++; |
991 | } |
992 | return std::string(OS.str()); |
993 | } |
994 | |
995 | static bool lookupStdTypeTraitMember(Sema &S, LookupResult &TraitMemberLookup, |
996 | SourceLocation Loc, StringRef Trait, |
997 | TemplateArgumentListInfo &Args, |
998 | unsigned DiagID) { |
999 | auto DiagnoseMissing = [&] { |
1000 | if (DiagID) |
1001 | S.Diag(Loc, DiagID) << printTemplateArgs(S.Context.getPrintingPolicy(), |
1002 | Args, nullptr); |
1003 | return true; |
1004 | }; |
1005 | |
1006 | |
1007 | NamespaceDecl *Std = S.getStdNamespace(); |
1008 | if (!Std) |
1009 | return DiagnoseMissing(); |
1010 | |
1011 | |
1012 | |
1013 | |
1014 | |
1015 | |
1016 | LookupResult Result(S, &S.PP.getIdentifierTable().get(Trait), |
1017 | Loc, Sema::LookupOrdinaryName); |
1018 | if (!S.LookupQualifiedName(Result, Std)) |
1019 | return DiagnoseMissing(); |
1020 | if (Result.isAmbiguous()) |
1021 | return true; |
1022 | |
1023 | ClassTemplateDecl *TraitTD = Result.getAsSingle<ClassTemplateDecl>(); |
1024 | if (!TraitTD) { |
1025 | Result.suppressDiagnostics(); |
1026 | NamedDecl *Found = *Result.begin(); |
1027 | S.Diag(Loc, diag::err_std_type_trait_not_class_template) << Trait; |
1028 | S.Diag(Found->getLocation(), diag::note_declared_at); |
1029 | return true; |
1030 | } |
1031 | |
1032 | |
1033 | QualType TraitTy = S.CheckTemplateIdType(TemplateName(TraitTD), Loc, Args); |
1034 | if (TraitTy.isNull()) |
1035 | return true; |
1036 | if (!S.isCompleteType(Loc, TraitTy)) { |
1037 | if (DiagID) |
1038 | S.RequireCompleteType( |
1039 | Loc, TraitTy, DiagID, |
1040 | printTemplateArgs(S.Context.getPrintingPolicy(), Args, |
1041 | TraitTD->getTemplateParameters())); |
1042 | return true; |
1043 | } |
1044 | |
1045 | CXXRecordDecl *RD = TraitTy->getAsCXXRecordDecl(); |
1046 | assert(RD && "specialization of class template is not a class?"); |
1047 | |
1048 | |
1049 | S.LookupQualifiedName(TraitMemberLookup, RD); |
1050 | return TraitMemberLookup.isAmbiguous(); |
1051 | } |
1052 | |
1053 | static TemplateArgumentLoc |
1054 | getTrivialIntegralTemplateArgument(Sema &S, SourceLocation Loc, QualType T, |
1055 | uint64_t I) { |
1056 | TemplateArgument Arg(S.Context, S.Context.MakeIntValue(I, T), T); |
1057 | return S.getTrivialTemplateArgumentLoc(Arg, T, Loc); |
1058 | } |
1059 | |
1060 | static TemplateArgumentLoc |
1061 | getTrivialTypeTemplateArgument(Sema &S, SourceLocation Loc, QualType T) { |
1062 | return S.getTrivialTemplateArgumentLoc(TemplateArgument(T), QualType(), Loc); |
1063 | } |
1064 | |
1065 | namespace { enum class IsTupleLike { TupleLike, NotTupleLike, Error }; } |
1066 | |
1067 | static IsTupleLike isTupleLike(Sema &S, SourceLocation Loc, QualType T, |
1068 | llvm::APSInt &Size) { |
1069 | EnterExpressionEvaluationContext ContextRAII( |
1070 | S, Sema::ExpressionEvaluationContext::ConstantEvaluated); |
1071 | |
1072 | DeclarationName Value = S.PP.getIdentifierInfo("value"); |
1073 | LookupResult R(S, Value, Loc, Sema::LookupOrdinaryName); |
1074 | |
1075 | |
1076 | TemplateArgumentListInfo Args(Loc, Loc); |
1077 | Args.addArgument(getTrivialTypeTemplateArgument(S, Loc, T)); |
1078 | |
1079 | |
1080 | |
1081 | if (lookupStdTypeTraitMember(S, R, Loc, "tuple_size", Args, 0) || |
1082 | R.empty()) |
1083 | return IsTupleLike::NotTupleLike; |
1084 | |
1085 | |
1086 | |
1087 | |
1088 | struct ICEDiagnoser : Sema::VerifyICEDiagnoser { |
1089 | LookupResult &R; |
1090 | TemplateArgumentListInfo &Args; |
1091 | ICEDiagnoser(LookupResult &R, TemplateArgumentListInfo &Args) |
1092 | : R(R), Args(Args) {} |
1093 | Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S, |
1094 | SourceLocation Loc) override { |
1095 | return S.Diag(Loc, diag::err_decomp_decl_std_tuple_size_not_constant) |
1096 | << printTemplateArgs(S.Context.getPrintingPolicy(), Args, |
1097 | nullptr); |
1098 | } |
1099 | } Diagnoser(R, Args); |
1100 | |
1101 | ExprResult E = |
1102 | S.BuildDeclarationNameExpr(CXXScopeSpec(), R, false); |
1103 | if (E.isInvalid()) |
1104 | return IsTupleLike::Error; |
1105 | |
1106 | E = S.VerifyIntegerConstantExpression(E.get(), &Size, Diagnoser); |
1107 | if (E.isInvalid()) |
1108 | return IsTupleLike::Error; |
1109 | |
1110 | return IsTupleLike::TupleLike; |
1111 | } |
1112 | |
1113 | |
1114 | static QualType getTupleLikeElementType(Sema &S, SourceLocation Loc, |
1115 | unsigned I, QualType T) { |
1116 | |
1117 | TemplateArgumentListInfo Args(Loc, Loc); |
1118 | Args.addArgument( |
1119 | getTrivialIntegralTemplateArgument(S, Loc, S.Context.getSizeType(), I)); |
1120 | Args.addArgument(getTrivialTypeTemplateArgument(S, Loc, T)); |
1121 | |
1122 | DeclarationName TypeDN = S.PP.getIdentifierInfo("type"); |
1123 | LookupResult R(S, TypeDN, Loc, Sema::LookupOrdinaryName); |
1124 | if (lookupStdTypeTraitMember( |
1125 | S, R, Loc, "tuple_element", Args, |
1126 | diag::err_decomp_decl_std_tuple_element_not_specialized)) |
1127 | return QualType(); |
1128 | |
1129 | auto *TD = R.getAsSingle<TypeDecl>(); |
1130 | if (!TD) { |
1131 | R.suppressDiagnostics(); |
1132 | S.Diag(Loc, diag::err_decomp_decl_std_tuple_element_not_specialized) |
1133 | << printTemplateArgs(S.Context.getPrintingPolicy(), Args, |
1134 | nullptr); |
1135 | if (!R.empty()) |
1136 | S.Diag(R.getRepresentativeDecl()->getLocation(), diag::note_declared_at); |
1137 | return QualType(); |
1138 | } |
1139 | |
1140 | return S.Context.getTypeDeclType(TD); |
1141 | } |
1142 | |
1143 | namespace { |
1144 | struct InitializingBinding { |
1145 | Sema &S; |
1146 | InitializingBinding(Sema &S, BindingDecl *BD) : S(S) { |
1147 | Sema::CodeSynthesisContext Ctx; |
1148 | Ctx.Kind = Sema::CodeSynthesisContext::InitializingStructuredBinding; |
1149 | Ctx.PointOfInstantiation = BD->getLocation(); |
1150 | Ctx.Entity = BD; |
1151 | S.pushCodeSynthesisContext(Ctx); |
1152 | } |
1153 | ~InitializingBinding() { |
1154 | S.popCodeSynthesisContext(); |
1155 | } |
1156 | }; |
1157 | } |
1158 | |
1159 | static bool checkTupleLikeDecomposition(Sema &S, |
1160 | ArrayRef<BindingDecl *> Bindings, |
1161 | VarDecl *Src, QualType DecompType, |
1162 | const llvm::APSInt &TupleSize) { |
1163 | if ((int64_t)Bindings.size() != TupleSize) { |
1164 | S.Diag(Src->getLocation(), diag::err_decomp_decl_wrong_number_bindings) |
1165 | << DecompType << (unsigned)Bindings.size() |
1166 | << (unsigned)TupleSize.getLimitedValue(UINT_MAX) |
1167 | << toString(TupleSize, 10) << (TupleSize < Bindings.size()); |
1168 | return true; |
1169 | } |
1170 | |
1171 | if (Bindings.empty()) |
1172 | return false; |
1173 | |
1174 | DeclarationName GetDN = S.PP.getIdentifierInfo("get"); |
1175 | |
1176 | |
1177 | |
1178 | |
1179 | LookupResult MemberGet(S, GetDN, Src->getLocation(), Sema::LookupMemberName); |
1180 | bool UseMemberGet = false; |
1181 | if (S.isCompleteType(Src->getLocation(), DecompType)) { |
1182 | if (auto *RD = DecompType->getAsCXXRecordDecl()) |
1183 | S.LookupQualifiedName(MemberGet, RD); |
1184 | if (MemberGet.isAmbiguous()) |
1185 | return true; |
1186 | |
1187 | |
1188 | for (NamedDecl *D : MemberGet) { |
1189 | if (FunctionTemplateDecl *FTD = |
1190 | dyn_cast<FunctionTemplateDecl>(D->getUnderlyingDecl())) { |
1191 | TemplateParameterList *TPL = FTD->getTemplateParameters(); |
1192 | if (TPL->size() != 0 && |
1193 | isa<NonTypeTemplateParmDecl>(TPL->getParam(0))) { |
1194 | |
1195 | UseMemberGet = true; |
1196 | break; |
1197 | } |
1198 | } |
1199 | } |
1200 | } |
1201 | |
1202 | unsigned I = 0; |
1203 | for (auto *B : Bindings) { |
1204 | InitializingBinding InitContext(S, B); |
1205 | SourceLocation Loc = B->getLocation(); |
1206 | |
1207 | ExprResult E = S.BuildDeclRefExpr(Src, DecompType, VK_LValue, Loc); |
1208 | if (E.isInvalid()) |
1209 | return true; |
1210 | |
1211 | |
1212 | |
1213 | if (!Src->getType()->isLValueReferenceType()) |
1214 | E = ImplicitCastExpr::Create(S.Context, E.get()->getType(), CK_NoOp, |
1215 | E.get(), nullptr, VK_XValue, |
1216 | FPOptionsOverride()); |
1217 | |
1218 | TemplateArgumentListInfo Args(Loc, Loc); |
1219 | Args.addArgument( |
1220 | getTrivialIntegralTemplateArgument(S, Loc, S.Context.getSizeType(), I)); |
1221 | |
1222 | if (UseMemberGet) { |
1223 | |
1224 | |
1225 | E = S.BuildMemberReferenceExpr(E.get(), DecompType, Loc, false, |
1226 | CXXScopeSpec(), SourceLocation(), nullptr, |
1227 | MemberGet, &Args, nullptr); |
1228 | if (E.isInvalid()) |
1229 | return true; |
1230 | |
1231 | E = S.BuildCallExpr(nullptr, E.get(), Loc, None, Loc); |
1232 | } else { |
1233 | |
1234 | |
1235 | Expr *Get = UnresolvedLookupExpr::Create( |
1236 | S.Context, nullptr, NestedNameSpecifierLoc(), SourceLocation(), |
1237 | DeclarationNameInfo(GetDN, Loc), true, &Args, |
1238 | UnresolvedSetIterator(), UnresolvedSetIterator()); |
1239 | |
1240 | Expr *Arg = E.get(); |
1241 | E = S.BuildCallExpr(nullptr, Get, Loc, Arg, Loc); |
1242 | } |
1243 | if (E.isInvalid()) |
1244 | return true; |
1245 | Expr *Init = E.get(); |
1246 | |
1247 | |
1248 | QualType T = getTupleLikeElementType(S, Loc, I, DecompType); |
1249 | if (T.isNull()) |
1250 | return true; |
1251 | |
1252 | |
1253 | |
1254 | |
1255 | QualType RefType = |
1256 | S.BuildReferenceType(T, E.get()->isLValue(), Loc, B->getDeclName()); |
1257 | if (RefType.isNull()) |
1258 | return true; |
1259 | auto *RefVD = VarDecl::Create( |
1260 | S.Context, Src->getDeclContext(), Loc, Loc, |
1261 | B->getDeclName().getAsIdentifierInfo(), RefType, |
1262 | S.Context.getTrivialTypeSourceInfo(T, Loc), Src->getStorageClass()); |
1263 | RefVD->setLexicalDeclContext(Src->getLexicalDeclContext()); |
1264 | RefVD->setTSCSpec(Src->getTSCSpec()); |
1265 | RefVD->setImplicit(); |
1266 | if (Src->isInlineSpecified()) |
1267 | RefVD->setInlineSpecified(); |
1268 | RefVD->getLexicalDeclContext()->addHiddenDecl(RefVD); |
1269 | |
1270 | InitializedEntity Entity = InitializedEntity::InitializeBinding(RefVD); |
1271 | InitializationKind Kind = InitializationKind::CreateCopy(Loc, Loc); |
1272 | InitializationSequence Seq(S, Entity, Kind, Init); |
1273 | E = Seq.Perform(S, Entity, Kind, Init); |
1274 | if (E.isInvalid()) |
1275 | return true; |
1276 | E = S.ActOnFinishFullExpr(E.get(), Loc, false); |
1277 | if (E.isInvalid()) |
1278 | return true; |
1279 | RefVD->setInit(E.get()); |
1280 | S.CheckCompleteVariableDeclaration(RefVD); |
1281 | |
1282 | E = S.BuildDeclarationNameExpr(CXXScopeSpec(), |
1283 | DeclarationNameInfo(B->getDeclName(), Loc), |
1284 | RefVD); |
1285 | if (E.isInvalid()) |
1286 | return true; |
1287 | |
1288 | B->setBinding(T, E.get()); |
1289 | I++; |
1290 | } |
1291 | |
1292 | return false; |
1293 | } |
1294 | |
1295 | |
1296 | |
1297 | |
1298 | static DeclAccessPair findDecomposableBaseClass(Sema &S, SourceLocation Loc, |
1299 | const CXXRecordDecl *RD, |
1300 | CXXCastPath &BasePath) { |
1301 | auto BaseHasFields = [](const CXXBaseSpecifier *Specifier, |
1302 | CXXBasePath &Path) { |
1303 | return Specifier->getType()->getAsCXXRecordDecl()->hasDirectFields(); |
1304 | }; |
1305 | |
1306 | const CXXRecordDecl *ClassWithFields = nullptr; |
1307 | AccessSpecifier AS = AS_public; |
1308 | if (RD->hasDirectFields()) |
| 16 | | Calling 'CXXRecordDecl::hasDirectFields' | |
|
| 20 | | Returning from 'CXXRecordDecl::hasDirectFields' | |
|
| 21 | | Assuming the condition is false | |
|
| |
1309 | |
1310 | |
1311 | |
1312 | ClassWithFields = RD; |
1313 | else { |
1314 | |
1315 | CXXBasePaths Paths; |
1316 | Paths.setOrigin(const_cast<CXXRecordDecl*>(RD)); |
1317 | if (!RD->lookupInBases(BaseHasFields, Paths)) { |
| 23 | | Assuming the condition is false | |
|
| |
1318 | |
1319 | |
1320 | return DeclAccessPair::make(const_cast<CXXRecordDecl*>(RD), AS_public); |
1321 | } |
1322 | |
1323 | CXXBasePath *BestPath = nullptr; |
| 25 | | 'BestPath' initialized to a null pointer value | |
|
1324 | for (auto &P : Paths) { |
1325 | if (!BestPath) |
1326 | BestPath = &P; |
1327 | else if (!S.Context.hasSameType(P.back().Base->getType(), |
1328 | BestPath->back().Base->getType())) { |
1329 | |
1330 | S.Diag(Loc, diag::err_decomp_decl_multiple_bases_with_members) |
1331 | << false << RD << BestPath->back().Base->getType() |
1332 | << P.back().Base->getType(); |
1333 | return DeclAccessPair(); |
1334 | } else if (P.Access < BestPath->Access) { |
1335 | BestPath = &P; |
1336 | } |
1337 | } |
1338 | |
1339 | |
1340 | QualType BaseType = BestPath->back().Base->getType(); |
| 26 | | Called C++ object pointer is null |
|
1341 | if (Paths.isAmbiguous(S.Context.getCanonicalType(BaseType))) { |
1342 | S.Diag(Loc, diag::err_decomp_decl_ambiguous_base) |
1343 | << RD << BaseType << S.getAmbiguousPathsDisplayString(Paths); |
1344 | return DeclAccessPair(); |
1345 | } |
1346 | |
1347 | |
1348 | S.CheckBaseClassAccess(Loc, BaseType, S.Context.getRecordType(RD), |
1349 | *BestPath, diag::err_decomp_decl_inaccessible_base); |
1350 | AS = BestPath->Access; |
1351 | |
1352 | ClassWithFields = BaseType->getAsCXXRecordDecl(); |
1353 | S.BuildBasePathArray(Paths, BasePath); |
1354 | } |
1355 | |
1356 | |
1357 | |
1358 | CXXBasePaths Paths; |
1359 | if (ClassWithFields->lookupInBases(BaseHasFields, Paths)) { |
1360 | S.Diag(Loc, diag::err_decomp_decl_multiple_bases_with_members) |
1361 | << (ClassWithFields == RD) << RD << ClassWithFields |
1362 | << Paths.front().back().Base->getType(); |
1363 | return DeclAccessPair(); |
1364 | } |
1365 | |
1366 | return DeclAccessPair::make(const_cast<CXXRecordDecl*>(ClassWithFields), AS); |
1367 | } |
1368 | |
1369 | static bool checkMemberDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings, |
1370 | ValueDecl *Src, QualType DecompType, |
1371 | const CXXRecordDecl *OrigRD) { |
1372 | if (S.RequireCompleteType(Src->getLocation(), DecompType, |
| 13 | | Assuming the condition is false | |
|
| |
1373 | diag::err_incomplete_type)) |
1374 | return true; |
1375 | |
1376 | CXXCastPath BasePath; |
1377 | DeclAccessPair BasePair = |
1378 | findDecomposableBaseClass(S, Src->getLocation(), OrigRD, BasePath); |
| 15 | | Calling 'findDecomposableBaseClass' | |
|
1379 | const CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(BasePair.getDecl()); |
1380 | if (!RD) |
1381 | return true; |
1382 | QualType BaseType = S.Context.getQualifiedType(S.Context.getRecordType(RD), |
1383 | DecompType.getQualifiers()); |
1384 | |
1385 | auto DiagnoseBadNumberOfBindings = [&]() -> bool { |
1386 | unsigned NumFields = |
1387 | std::count_if(RD->field_begin(), RD->field_end(), |
1388 | [](FieldDecl *FD) { return !FD->isUnnamedBitfield(); }); |
1389 | assert(Bindings.size() != NumFields); |
1390 | S.Diag(Src->getLocation(), diag::err_decomp_decl_wrong_number_bindings) |
1391 | << DecompType << (unsigned)Bindings.size() << NumFields << NumFields |
1392 | << (NumFields < Bindings.size()); |
1393 | return true; |
1394 | }; |
1395 | |
1396 | |
1397 | |
1398 | |
1399 | unsigned I = 0; |
1400 | for (auto *FD : RD->fields()) { |
1401 | if (FD->isUnnamedBitfield()) |
1402 | continue; |
1403 | |
1404 | |
1405 | |
1406 | if (!FD->getDeclName()) { |
1407 | if (RD->isLambda()) { |
1408 | S.Diag(Src->getLocation(), diag::err_decomp_decl_lambda); |
1409 | S.Diag(RD->getLocation(), diag::note_lambda_decl); |
1410 | return true; |
1411 | } |
1412 | |
1413 | if (FD->isAnonymousStructOrUnion()) { |
1414 | S.Diag(Src->getLocation(), diag::err_decomp_decl_anon_union_member) |
1415 | << DecompType << FD->getType()->isUnionType(); |
1416 | S.Diag(FD->getLocation(), diag::note_declared_at); |
1417 | return true; |
1418 | } |
1419 | |
1420 | |
1421 | } |
1422 | |
1423 | |
1424 | if (I >= Bindings.size()) |
1425 | return DiagnoseBadNumberOfBindings(); |
1426 | auto *B = Bindings[I++]; |
1427 | SourceLocation Loc = B->getLocation(); |
1428 | |
1429 | |
1430 | |
1431 | |
1432 | |
1433 | S.CheckStructuredBindingMemberAccess( |
1434 | Loc, const_cast<CXXRecordDecl *>(OrigRD), |
1435 | DeclAccessPair::make(FD, CXXRecordDecl::MergeAccess( |
1436 | BasePair.getAccess(), FD->getAccess()))); |
1437 | |
1438 | |
1439 | ExprResult E = S.BuildDeclRefExpr(Src, DecompType, VK_LValue, Loc); |
1440 | if (E.isInvalid()) |
1441 | return true; |
1442 | E = S.ImpCastExprToType(E.get(), BaseType, CK_UncheckedDerivedToBase, |
1443 | VK_LValue, &BasePath); |
1444 | if (E.isInvalid()) |
1445 | return true; |
1446 | E = S.BuildFieldReferenceExpr(E.get(), false, Loc, |
1447 | CXXScopeSpec(), FD, |
1448 | DeclAccessPair::make(FD, FD->getAccess()), |
1449 | DeclarationNameInfo(FD->getDeclName(), Loc)); |
1450 | if (E.isInvalid()) |
1451 | return true; |
1452 | |
1453 | |
1454 | |
1455 | |
1456 | |
1457 | |
1458 | Qualifiers Q = DecompType.getQualifiers(); |
1459 | if (FD->isMutable()) |
1460 | Q.removeConst(); |
1461 | B->setBinding(S.BuildQualifiedType(FD->getType(), Loc, Q), E.get()); |
1462 | } |
1463 | |
1464 | if (I != Bindings.size()) |
1465 | return DiagnoseBadNumberOfBindings(); |
1466 | |
1467 | return false; |
1468 | } |
1469 | |
1470 | void Sema::CheckCompleteDecompositionDeclaration(DecompositionDecl *DD) { |
1471 | QualType DecompType = DD->getType(); |
1472 | |
1473 | |
1474 | |
1475 | if (DecompType->isDependentType()) { |
| 1 | Assuming the condition is false | |
|
| |
1476 | for (auto *B : DD->bindings()) |
1477 | B->setType(Context.DependentTy); |
1478 | return; |
1479 | } |
1480 | |
1481 | DecompType = DecompType.getNonReferenceType(); |
1482 | ArrayRef<BindingDecl*> Bindings = DD->bindings(); |
1483 | |
1484 | |
1485 | |
1486 | |
1487 | |
1488 | if (auto *CAT = Context.getAsConstantArrayType(DecompType)) { |
| |
1489 | if (checkArrayDecomposition(*this, Bindings, DD, DecompType, CAT)) |
1490 | DD->setInvalidDecl(); |
1491 | return; |
1492 | } |
1493 | if (auto *VT = DecompType->getAs<VectorType>()) { |
| 4 | | Assuming the object is not a 'VectorType' | |
|
| |
1494 | if (checkVectorDecomposition(*this, Bindings, DD, DecompType, VT)) |
1495 | DD->setInvalidDecl(); |
1496 | return; |
1497 | } |
1498 | if (auto *CT = DecompType->getAs<ComplexType>()) { |
| 6 | | Assuming the object is not a 'ComplexType' | |
|
| |
1499 | if (checkComplexDecomposition(*this, Bindings, DD, DecompType, CT)) |
1500 | DD->setInvalidDecl(); |
1501 | return; |
1502 | } |
1503 | |
1504 | |
1505 | |
1506 | |
1507 | llvm::APSInt TupleSize(32); |
1508 | switch (isTupleLike(*this, DD->getLocation(), DecompType, TupleSize)) { |
| 8 | | Control jumps to 'case NotTupleLike:' at line 1518 | |
|
1509 | case IsTupleLike::Error: |
1510 | DD->setInvalidDecl(); |
1511 | return; |
1512 | |
1513 | case IsTupleLike::TupleLike: |
1514 | if (checkTupleLikeDecomposition(*this, Bindings, DD, DecompType, TupleSize)) |
1515 | DD->setInvalidDecl(); |
1516 | return; |
1517 | |
1518 | case IsTupleLike::NotTupleLike: |
1519 | break; |
| 9 | | Execution continues on line 1524 | |
|
1520 | } |
1521 | |
1522 | |
1523 | |
1524 | CXXRecordDecl *RD = DecompType->getAsCXXRecordDecl(); |
1525 | if (!RD || RD->isUnion()) { |
| 10 | | Assuming 'RD' is non-null | |
|
| |
1526 | Diag(DD->getLocation(), diag::err_decomp_decl_unbindable_type) |
1527 | << DD << !RD << DecompType; |
1528 | DD->setInvalidDecl(); |
1529 | return; |
1530 | } |
1531 | |
1532 | |
1533 | |
1534 | |
1535 | if (checkMemberDecomposition(*this, Bindings, DD, DecompType, RD)) |
| 12 | | Calling 'checkMemberDecomposition' | |
|
1536 | DD->setInvalidDecl(); |
1537 | } |
1538 | |
1539 | |
1540 | |
1541 | |
1542 | |
1543 | |
1544 | void Sema::MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old) { |
1545 | |
1546 | if (!getLangOpts().CXXExceptions) |
1547 | return; |
1548 | |
1549 | assert(Context.hasSameType(New->getType(), Old->getType()) && |
1550 | "Should only be called if types are otherwise the same."); |
1551 | |
1552 | QualType NewType = New->getType(); |
1553 | QualType OldType = Old->getType(); |
1554 | |
1555 | |
1556 | |
1557 | if (const ReferenceType *R = NewType->getAs<ReferenceType>()) { |
1558 | NewType = R->getPointeeType(); |
1559 | OldType = OldType->castAs<ReferenceType>()->getPointeeType(); |
1560 | } else if (const PointerType *P = NewType->getAs<PointerType>()) { |
1561 | NewType = P->getPointeeType(); |
1562 | OldType = OldType->castAs<PointerType>()->getPointeeType(); |
1563 | } else if (const MemberPointerType *M = NewType->getAs<MemberPointerType>()) { |
1564 | NewType = M->getPointeeType(); |
1565 | OldType = OldType->castAs<MemberPointerType>()->getPointeeType(); |
1566 | } |
1567 | |
1568 | if (!NewType->isFunctionProtoType()) |
1569 | return; |
1570 | |
1571 | |
1572 | |
1573 | |
1574 | if (CheckEquivalentExceptionSpec( |
1575 | OldType->getAs<FunctionProtoType>(), Old->getLocation(), |
1576 | NewType->getAs<FunctionProtoType>(), New->getLocation())) { |
1577 | New->setInvalidDecl(); |
1578 | } |
1579 | } |
1580 | |
1581 | |
1582 | |
1583 | |
1584 | void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) { |
1585 | unsigned NumParams = FD->getNumParams(); |
1586 | unsigned ParamIdx = 0; |
1587 | |
1588 | |
1589 | |
1590 | |
1591 | if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) |
1592 | return; |
1593 | if (auto *FTD = FD->getDescribedFunctionTemplate()) |
1594 | if (FTD->isMemberSpecialization()) |
1595 | return; |
1596 | |
1597 | |
1598 | for (; ParamIdx < NumParams; ++ParamIdx) { |
1599 | ParmVarDecl *Param = FD->getParamDecl(ParamIdx); |
1600 | if (Param->hasDefaultArg()) |
1601 | break; |
1602 | } |
1603 | |
1604 | |
1605 | |
1606 | |
1607 | |
1608 | |
1609 | for (; ParamIdx < NumParams; ++ParamIdx) { |
1610 | ParmVarDecl *Param = FD->getParamDecl(ParamIdx); |
1611 | if (!Param->hasDefaultArg() && !Param->isParameterPack() && |
1612 | !(CurrentInstantiationScope && |
1613 | CurrentInstantiationScope->isLocalPackExpansion(Param))) { |
1614 | if (Param->isInvalidDecl()) |
1615 | ; |
1616 | else if (Param->getIdentifier()) |
1617 | Diag(Param->getLocation(), |
1618 | diag::err_param_default_argument_missing_name) |
1619 | << Param->getIdentifier(); |
1620 | else |
1621 | Diag(Param->getLocation(), |
1622 | diag::err_param_default_argument_missing); |
1623 | } |
1624 | } |
1625 | } |
1626 | |
1627 | |
1628 | |
1629 | |
1630 | template <typename... Ts> |
1631 | static bool CheckLiteralType(Sema &SemaRef, Sema::CheckConstexprKind Kind, |
1632 | SourceLocation Loc, QualType T, unsigned DiagID, |
1633 | Ts &&...DiagArgs) { |
1634 | if (T->isDependentType()) |
1635 | return false; |
1636 | |
1637 | switch (Kind) { |
1638 | case Sema::CheckConstexprKind::Diagnose: |
1639 | return SemaRef.RequireLiteralType(Loc, T, DiagID, |
1640 | std::forward<Ts>(DiagArgs)...); |
1641 | |
1642 | case Sema::CheckConstexprKind::CheckValid: |
1643 | return !T->isLiteralType(SemaRef.Context); |
1644 | } |
1645 | |
1646 | llvm_unreachable("unknown CheckConstexprKind"); |
1647 | } |
1648 | |
1649 | |
1650 | static bool CheckConstexprDestructorSubobjects(Sema &SemaRef, |
1651 | const CXXDestructorDecl *DD, |
1652 | Sema::CheckConstexprKind Kind) { |
1653 | auto Check = [&](SourceLocation Loc, QualType T, const FieldDecl *FD) { |
1654 | const CXXRecordDecl *RD = |
1655 | T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl(); |
1656 | if (!RD || RD->hasConstexprDestructor()) |
1657 | return true; |
1658 | |
1659 | if (Kind == Sema::CheckConstexprKind::Diagnose) { |
1660 | SemaRef.Diag(DD->getLocation(), diag::err_constexpr_dtor_subobject) |
1661 | << static_cast<int>(DD->getConstexprKind()) << !FD |
1662 | << (FD ? FD->getDeclName() : DeclarationName()) << T; |
1663 | SemaRef.Diag(Loc, diag::note_constexpr_dtor_subobject) |
1664 | << !FD << (FD ? FD->getDeclName() : DeclarationName()) << T; |
1665 | } |
1666 | return false; |
1667 | }; |
1668 | |
1669 | const CXXRecordDecl *RD = DD->getParent(); |
1670 | for (const CXXBaseSpecifier &B : RD->bases()) |
1671 | if (!Check(B.getBaseTypeLoc(), B.getType(), nullptr)) |
1672 | return false; |
1673 | for (const FieldDecl *FD : RD->fields()) |
1674 | if (!Check(FD->getLocation(), FD->getType(), FD)) |
1675 | return false; |
1676 | return true; |
1677 | } |
1678 | |
1679 | |
1680 | |
1681 | static bool CheckConstexprParameterTypes(Sema &SemaRef, |
1682 | const FunctionDecl *FD, |
1683 | Sema::CheckConstexprKind Kind) { |
1684 | unsigned ArgIndex = 0; |
1685 | const auto *FT = FD->getType()->castAs<FunctionProtoType>(); |
1686 | for (FunctionProtoType::param_type_iterator i = FT->param_type_begin(), |
1687 | e = FT->param_type_end(); |
1688 | i != e; ++i, ++ArgIndex) { |
1689 | const ParmVarDecl *PD = FD->getParamDecl(ArgIndex); |
1690 | SourceLocation ParamLoc = PD->getLocation(); |
1691 | if (CheckLiteralType(SemaRef, Kind, ParamLoc, *i, |
1692 | diag::err_constexpr_non_literal_param, ArgIndex + 1, |
1693 | PD->getSourceRange(), isa<CXXConstructorDecl>(FD), |
1694 | FD->isConsteval())) |
1695 | return false; |
1696 | } |
1697 | return true; |
1698 | } |
1699 | |
1700 | |
1701 | |
1702 | static bool CheckConstexprReturnType(Sema &SemaRef, const FunctionDecl *FD, |
1703 | Sema::CheckConstexprKind Kind) { |
1704 | if (CheckLiteralType(SemaRef, Kind, FD->getLocation(), FD->getReturnType(), |
1705 | diag::err_constexpr_non_literal_return, |
1706 | FD->isConsteval())) |
1707 | return false; |
1708 | return true; |
1709 | } |
1710 | |
1711 | |
1712 | |
1713 | |
1714 | |
1715 | |
1716 | static unsigned getRecordDiagFromTagKind(TagTypeKind Tag) { |
1717 | switch (Tag) { |
1718 | case TTK_Struct: return 0; |
1719 | case TTK_Interface: return 1; |
1720 | case TTK_Class: return 2; |
1721 | default: llvm_unreachable("Invalid tag kind for record diagnostic!"); |
1722 | } |
1723 | } |
1724 | |
1725 | static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl, |
1726 | Stmt *Body, |
1727 | Sema::CheckConstexprKind Kind); |
1728 | |
1729 | |
1730 | |
1731 | |
1732 | |
1733 | |
1734 | |
1735 | bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD, |
1736 | CheckConstexprKind Kind) { |
1737 | const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); |
1738 | if (MD && MD->isInstance()) { |
1739 | |
1740 | |
1741 | |
1742 | |
1743 | |
1744 | |
1745 | |
1746 | const CXXRecordDecl *RD = MD->getParent(); |
1747 | if (RD->getNumVBases()) { |
1748 | if (Kind == CheckConstexprKind::CheckValid) |
1749 | return false; |
1750 | |
1751 | Diag(NewFD->getLocation(), diag::err_constexpr_virtual_base) |
1752 | << isa<CXXConstructorDecl>(NewFD) |
1753 | << getRecordDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases(); |
1754 | for (const auto &I : RD->vbases()) |
1755 | Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here) |
1756 | << I.getSourceRange(); |
1757 | return false; |
1758 | } |
1759 | } |
1760 | |
1761 | if (!isa<CXXConstructorDecl>(NewFD)) { |
1762 | |
1763 | |
1764 | |
1765 | |
1766 | const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(NewFD); |
1767 | if (Method && Method->isVirtual()) { |
1768 | if (getLangOpts().CPlusPlus20) { |
1769 | if (Kind == CheckConstexprKind::Diagnose) |
1770 | Diag(Method->getLocation(), diag::warn_cxx17_compat_constexpr_virtual); |
1771 | } else { |
1772 | if (Kind == CheckConstexprKind::CheckValid) |
1773 | return false; |
1774 | |
1775 | Method = Method->getCanonicalDecl(); |
1776 | Diag(Method->getLocation(), diag::err_constexpr_virtual); |
1777 | |
1778 | |
1779 | |
1780 | const CXXMethodDecl *WrittenVirtual = Method; |
1781 | while (!WrittenVirtual->isVirtualAsWritten()) |
1782 | WrittenVirtual = *WrittenVirtual->begin_overridden_methods(); |
1783 | if (WrittenVirtual != Method) |
1784 | Diag(WrittenVirtual->getLocation(), |
1785 | diag::note_overridden_virtual_function); |
1786 | return false; |
1787 | } |
1788 | } |
1789 | |
1790 | |
1791 | if (!CheckConstexprReturnType(*this, NewFD, Kind)) |
1792 | return false; |
1793 | } |
1794 | |
1795 | if (auto *Dtor = dyn_cast<CXXDestructorDecl>(NewFD)) { |
1796 | |
1797 | |
1798 | |
1799 | if (!Dtor->getParent()->defaultedDestructorIsConstexpr()) { |
1800 | if (Kind == CheckConstexprKind::CheckValid) |
1801 | return false; |
1802 | if (!CheckConstexprDestructorSubobjects(*this, Dtor, Kind)) |
1803 | return false; |
1804 | } |
1805 | } |
1806 | |
1807 | |
1808 | if (!CheckConstexprParameterTypes(*this, NewFD, Kind)) |
1809 | return false; |
1810 | |
1811 | Stmt *Body = NewFD->getBody(); |
1812 | assert(Body && |
1813 | "CheckConstexprFunctionDefinition called on function with no body"); |
1814 | return CheckConstexprFunctionBody(*this, NewFD, Body, Kind); |
1815 | } |
1816 | |
1817 | |
1818 | |
1819 | |
1820 | |
1821 | |
1822 | static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl, |
1823 | DeclStmt *DS, SourceLocation &Cxx1yLoc, |
1824 | Sema::CheckConstexprKind Kind) { |
1825 | |
1826 | |
1827 | |
1828 | for (const auto *DclIt : DS->decls()) { |
1829 | switch (DclIt->getKind()) { |
1830 | case Decl::StaticAssert: |
1831 | case Decl::Using: |
1832 | case Decl::UsingShadow: |
1833 | case Decl::UsingDirective: |
1834 | case Decl::UnresolvedUsingTypename: |
1835 | case Decl::UnresolvedUsingValue: |
1836 | case Decl::UsingEnum: |
1837 | |
1838 | |
1839 | |
1840 | |
1841 | continue; |
1842 | |
1843 | case Decl::Typedef: |
1844 | case Decl::TypeAlias: { |
1845 | |
1846 | |
1847 | const auto *TN = cast<TypedefNameDecl>(DclIt); |
1848 | if (TN->getUnderlyingType()->isVariablyModifiedType()) { |
1849 | |
1850 | if (Kind == Sema::CheckConstexprKind::Diagnose) { |
1851 | TypeLoc TL = TN->getTypeSourceInfo()->getTypeLoc(); |
1852 | SemaRef.Diag(TL.getBeginLoc(), diag::err_constexpr_vla) |
1853 | << TL.getSourceRange() << TL.getType() |
1854 | << isa<CXXConstructorDecl>(Dcl); |
1855 | } |
1856 | return false; |
1857 | } |
1858 | continue; |
1859 | } |
1860 | |
1861 | case Decl::Enum: |
1862 | case Decl::CXXRecord: |
1863 | |
1864 | if (cast<TagDecl>(DclIt)->isThisDeclarationADefinition()) { |
1865 | if (Kind == Sema::CheckConstexprKind::Diagnose) { |
1866 | SemaRef.Diag(DS->getBeginLoc(), |
1867 | SemaRef.getLangOpts().CPlusPlus14 |
1868 | ? diag::warn_cxx11_compat_constexpr_type_definition |
1869 | : diag::ext_constexpr_type_definition) |
1870 | << isa<CXXConstructorDecl>(Dcl); |
1871 | } else if (!SemaRef.getLangOpts().CPlusPlus14) { |
1872 | return false; |
1873 | } |
1874 | } |
1875 | continue; |
1876 | |
1877 | case Decl::EnumConstant: |
1878 | case Decl::IndirectField: |
1879 | case Decl::ParmVar: |
1880 | |
1881 | |
1882 | continue; |
1883 | |
1884 | case Decl::Var: |
1885 | case Decl::Decomposition: { |
1886 | |
1887 | |
1888 | |
1889 | |
1890 | const auto *VD = cast<VarDecl>(DclIt); |
1891 | if (VD->isThisDeclarationADefinition()) { |
1892 | if (VD->isStaticLocal()) { |
1893 | if (Kind == Sema::CheckConstexprKind::Diagnose) { |
1894 | SemaRef.Diag(VD->getLocation(), |
1895 | diag::err_constexpr_local_var_static) |
1896 | << isa<CXXConstructorDecl>(Dcl) |
1897 | << (VD->getTLSKind() == VarDecl::TLS_Dynamic); |
1898 | } |
1899 | return false; |
1900 | } |
1901 | if (CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(), |
1902 | diag::err_constexpr_local_var_non_literal_type, |
1903 | isa<CXXConstructorDecl>(Dcl))) |
1904 | return false; |
1905 | if (!VD->getType()->isDependentType() && |
1906 | !VD->hasInit() && !VD->isCXXForRangeDecl()) { |
1907 | if (Kind == Sema::CheckConstexprKind::Diagnose) { |
1908 | SemaRef.Diag( |
1909 | VD->getLocation(), |
1910 | SemaRef.getLangOpts().CPlusPlus20 |
1911 | ? diag::warn_cxx17_compat_constexpr_local_var_no_init |
1912 | : diag::ext_constexpr_local_var_no_init) |
1913 | << isa<CXXConstructorDecl>(Dcl); |
1914 | } else if (!SemaRef.getLangOpts().CPlusPlus20) { |
1915 | return false; |
1916 | } |
1917 | continue; |
1918 | } |
1919 | } |
1920 | if (Kind == Sema::CheckConstexprKind::Diagnose) { |
1921 | SemaRef.Diag(VD->getLocation(), |
1922 | SemaRef.getLangOpts().CPlusPlus14 |
1923 | ? diag::warn_cxx11_compat_constexpr_local_var |
1924 | : diag::ext_constexpr_local_var) |
1925 | << isa<CXXConstructorDecl>(Dcl); |
1926 | } else if (!SemaRef.getLangOpts().CPlusPlus14) { |
1927 | return false; |
1928 | } |
1929 | continue; |
1930 | } |
1931 | |
1932 | case Decl::NamespaceAlias: |
1933 | case Decl::Function: |
1934 | |
1935 | |
1936 | if (!Cxx1yLoc.isValid()) |
1937 | Cxx1yLoc = DS->getBeginLoc(); |
1938 | continue; |
1939 | |
1940 | default: |
1941 | if (Kind == Sema::CheckConstexprKind::Diagnose) { |
1942 | SemaRef.Diag(DS->getBeginLoc(), diag::err_constexpr_body_invalid_stmt) |
1943 | << isa<CXXConstructorDecl>(Dcl) << Dcl->isConsteval(); |
1944 | } |
1945 | return false; |
1946 | } |
1947 | } |
1948 | |
1949 | return true; |
1950 | } |
1951 | |
1952 | |
1953 | |
1954 | |
1955 | |
1956 | |
1957 | |
1958 | |
1959 | |
1960 | |
1961 | |
1962 | |
1963 | |
1964 | |
1965 | static bool CheckConstexprCtorInitializer(Sema &SemaRef, |
1966 | const FunctionDecl *Dcl, |
1967 | FieldDecl *Field, |
1968 | llvm::SmallSet<Decl*, 16> &Inits, |
1969 | bool &Diagnosed, |
1970 | Sema::CheckConstexprKind Kind) { |
1971 | |
1972 | if (Kind == Sema::CheckConstexprKind::CheckValid && |
1973 | SemaRef.getLangOpts().CPlusPlus20) |
1974 | return true; |
1975 | |
1976 | if (Field->isInvalidDecl()) |
1977 | return true; |
1978 | |
1979 | if (Field->isUnnamedBitfield()) |
1980 | return true; |
1981 | |
1982 | |
1983 | |
1984 | |
1985 | if (Field->isAnonymousStructOrUnion() && |
1986 | (Field->getType()->isUnionType() |
1987 | ? !Field->getType()->getAsCXXRecordDecl()->hasVariantMembers() |
1988 | : Field->getType()->getAsCXXRecordDecl()->isEmpty())) |
1989 | return true; |
1990 | |
1991 | if (!Inits.count(Field)) { |
1992 | if (Kind == Sema::CheckConstexprKind::Diagnose) { |
1993 | if (!Diagnosed) { |
1994 | SemaRef.Diag(Dcl->getLocation(), |
1995 | SemaRef.getLangOpts().CPlusPlus20 |
1996 | ? diag::warn_cxx17_compat_constexpr_ctor_missing_init |
1997 | : diag::ext_constexpr_ctor_missing_init); |
1998 | Diagnosed = true; |
1999 | } |
2000 | SemaRef.Diag(Field->getLocation(), |
2001 | diag::note_constexpr_ctor_missing_init); |
2002 | } else if (!SemaRef.getLangOpts().CPlusPlus20) { |
2003 | return false; |
2004 | } |
2005 | } else if (Field->isAnonymousStructOrUnion()) { |
2006 | const RecordDecl *RD = Field->getType()->castAs<RecordType>()->getDecl(); |
2007 | for (auto *I : RD->fields()) |
2008 | |
2009 | |
2010 | if (!RD->isUnion() || Inits.count(I)) |
2011 | if (!CheckConstexprCtorInitializer(SemaRef, Dcl, I, Inits, Diagnosed, |
2012 | Kind)) |
2013 | return false; |
2014 | } |
2015 | return true; |
2016 | } |
2017 | |
2018 | |
2019 | |
2020 | static bool |
2021 | CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S, |
2022 | SmallVectorImpl<SourceLocation> &ReturnStmts, |
2023 | SourceLocation &Cxx1yLoc, SourceLocation &Cxx2aLoc, |
2024 | Sema::CheckConstexprKind Kind) { |
2025 | |
2026 | switch (S->getStmtClass()) { |
2027 | case Stmt::NullStmtClass: |
2028 | |
2029 | return true; |
2030 | |
2031 | case Stmt::DeclStmtClass: |
2032 | |
2033 | |
2034 | |
2035 | |
2036 | |
2037 | if (!CheckConstexprDeclStmt(SemaRef, Dcl, cast<DeclStmt>(S), Cxx1yLoc, Kind)) |
2038 | return false; |
2039 | return true; |
2040 | |
2041 | case Stmt::ReturnStmtClass: |
2042 | |
2043 | if (isa<CXXConstructorDecl>(Dcl)) { |
2044 | |
2045 | if (!Cxx1yLoc.isValid()) |
2046 | Cxx1yLoc = S->getBeginLoc(); |
2047 | return true; |
2048 | } |
2049 | |
2050 | ReturnStmts.push_back(S->getBeginLoc()); |
2051 | return true; |
2052 | |
2053 | case Stmt::CompoundStmtClass: { |
2054 | |
2055 | if (!Cxx1yLoc.isValid()) |
2056 | Cxx1yLoc = S->getBeginLoc(); |
2057 | |
2058 | CompoundStmt *CompStmt = cast<CompoundStmt>(S); |
2059 | for (auto *BodyIt : CompStmt->body()) { |
2060 | if (!CheckConstexprFunctionStmt(SemaRef, Dcl, BodyIt, ReturnStmts, |
2061 | Cxx1yLoc, Cxx2aLoc, Kind)) |
2062 | return false; |
2063 | } |
2064 | return true; |
2065 | } |
2066 | |
2067 | case Stmt::AttributedStmtClass: |
2068 | if (!Cxx1yLoc.isValid()) |
2069 | Cxx1yLoc = S->getBeginLoc(); |
2070 | return true; |
2071 | |
2072 | case Stmt::IfStmtClass: { |
2073 | |
2074 | if (!Cxx1yLoc.isValid()) |
2075 | Cxx1yLoc = S->getBeginLoc(); |
2076 | |
2077 | IfStmt *If = cast<IfStmt>(S); |
2078 | if (!CheckConstexprFunctionStmt(SemaRef, Dcl, If->getThen(), ReturnStmts, |
2079 | Cxx1yLoc, Cxx2aLoc, Kind)) |
2080 | return false; |
2081 | if (If->getElse() && |
2082 | !CheckConstexprFunctionStmt(SemaRef, Dcl, If->getElse(), ReturnStmts, |
2083 | Cxx1yLoc, Cxx2aLoc, Kind)) |
2084 | return false; |
2085 | return true; |
2086 | } |
2087 | |
2088 | case Stmt::WhileStmtClass: |
2089 | case Stmt::DoStmtClass: |
2090 | case Stmt::ForStmtClass: |
2091 | case Stmt::CXXForRangeStmtClass: |
2092 | case Stmt::ContinueStmtClass: |
2093 | |
2094 | |
2095 | if (!SemaRef.getLangOpts().CPlusPlus14) |
2096 | break; |
2097 | if (!Cxx1yLoc.isValid()) |
2098 | Cxx1yLoc = S->getBeginLoc(); |
2099 | for (Stmt *SubStmt : S->children()) |
2100 | if (SubStmt && |
2101 | !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts, |
2102 | Cxx1yLoc, Cxx2aLoc, Kind)) |
2103 | return false; |
2104 | return true; |
2105 | |
2106 | case Stmt::SwitchStmtClass: |
2107 | case Stmt::CaseStmtClass: |
2108 | case Stmt::DefaultStmtClass: |
2109 | case Stmt::BreakStmtClass: |
2110 | |
2111 | |
2112 | if (!Cxx1yLoc.isValid()) |
2113 | Cxx1yLoc = S->getBeginLoc(); |
2114 | for (Stmt *SubStmt : S->children()) |
2115 | if (SubStmt && |
2116 | !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts, |
2117 | Cxx1yLoc, Cxx2aLoc, Kind)) |
2118 | return false; |
2119 | return true; |
2120 | |
2121 | case Stmt::GCCAsmStmtClass: |
2122 | case Stmt::MSAsmStmtClass: |
2123 | |
2124 | case Stmt::CXXTryStmtClass: |
2125 | if (Cxx2aLoc.isInvalid()) |
2126 | Cxx2aLoc = S->getBeginLoc(); |
2127 | for (Stmt *SubStmt : S->children()) { |
2128 | if (SubStmt && |
2129 | !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts, |
2130 | Cxx1yLoc, Cxx2aLoc, Kind)) |
2131 | return false; |
2132 | } |
2133 | return true; |
2134 | |
2135 | case Stmt::CXXCatchStmtClass: |
2136 | |
2137 | |
2138 | if (!CheckConstexprFunctionStmt(SemaRef, Dcl, |
2139 | cast<CXXCatchStmt>(S)->getHandlerBlock(), |
2140 | ReturnStmts, Cxx1yLoc, Cxx2aLoc, Kind)) |
2141 | return false; |
2142 | return true; |
2143 | |
2144 | default: |
2145 | if (!isa<Expr>(S)) |
2146 | break; |
2147 | |
2148 | |
2149 | if (!Cxx1yLoc.isValid()) |
2150 | Cxx1yLoc = S->getBeginLoc(); |
2151 | return true; |
2152 | } |
2153 | |
2154 | if (Kind == Sema::CheckConstexprKind::Diagnose) { |
2155 | SemaRef.Diag(S->getBeginLoc(), diag::err_constexpr_body_invalid_stmt) |
2156 | << isa<CXXConstructorDecl>(Dcl) << Dcl->isConsteval(); |
2157 | } |
2158 | return false; |
2159 | } |
2160 | |
2161 | |
2162 | |
2163 | |
2164 | |
2165 | |
2166 | static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl, |
2167 | Stmt *Body, |
2168 | Sema::CheckConstexprKind Kind) { |
2169 | SmallVector<SourceLocation, 4> ReturnStmts; |
2170 | |
2171 | if (isa<CXXTryStmt>(Body)) { |
2172 | |
2173 | |
2174 | |
2175 | |
2176 | |
2177 | |
2178 | |
2179 | |
2180 | |
2181 | |
2182 | |
2183 | |
2184 | switch (Kind) { |
2185 | case Sema::CheckConstexprKind::CheckValid: |
2186 | if (!SemaRef.getLangOpts().CPlusPlus20) |
2187 | return false; |
2188 | break; |
2189 | |
2190 | case Sema::CheckConstexprKind::Diagnose: |
2191 | SemaRef.Diag(Body->getBeginLoc(), |
2192 | !SemaRef.getLangOpts().CPlusPlus20 |
2193 | ? diag::ext_constexpr_function_try_block_cxx20 |
2194 | : diag::warn_cxx17_compat_constexpr_function_try_block) |
2195 | << isa<CXXConstructorDecl>(Dcl); |
2196 | break; |
2197 | } |
2198 | } |
2199 | |
2200 | |
2201 | |
2202 | |
2203 | |
2204 | |
2205 | SourceLocation Cxx1yLoc, Cxx2aLoc; |
2206 | for (Stmt *SubStmt : Body->children()) { |
2207 | if (SubStmt && |
2208 | !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts, |
2209 | Cxx1yLoc, Cxx2aLoc, Kind)) |
2210 | return false; |
2211 | } |
2212 | |
2213 | if (Kind == Sema::CheckConstexprKind::CheckValid) { |
2214 | |
2215 | |
2216 | if ((Cxx2aLoc.isValid() && !SemaRef.getLangOpts().CPlusPlus20) || |
2217 | (Cxx1yLoc.isValid() && !SemaRef.getLangOpts().CPlusPlus17)) |
2218 | return false; |
2219 | } else if (Cxx2aLoc.isValid()) { |
2220 | SemaRef.Diag(Cxx2aLoc, |
2221 | SemaRef.getLangOpts().CPlusPlus20 |
2222 | ? diag::warn_cxx17_compat_constexpr_body_invalid_stmt |
2223 | : diag::ext_constexpr_body_invalid_stmt_cxx20) |
2224 | << isa<CXXConstructorDecl>(Dcl); |
2225 | } else if (Cxx1yLoc.isValid()) { |
2226 | SemaRef.Diag(Cxx1yLoc, |
2227 | SemaRef.getLangOpts().CPlusPlus14 |
2228 | ? diag::warn_cxx11_compat_constexpr_body_invalid_stmt |
2229 | : diag::ext_constexpr_body_invalid_stmt) |
2230 | << isa<CXXConstructorDecl>(Dcl); |
2231 | } |
2232 | |
2233 | if (const CXXConstructorDecl *Constructor |
2234 | = dyn_cast<CXXConstructorDecl>(Dcl)) { |
2235 | const CXXRecordDecl *RD = Constructor->getParent(); |
2236 | |
2237 | |
2238 | |
2239 | |
2240 | |
2241 | |
2242 | if (RD->isUnion()) { |
2243 | if (Constructor->getNumCtorInitializers() == 0 && |
2244 | RD->hasVariantMembers()) { |
2245 | if (Kind == Sema::CheckConstexprKind::Diagnose) { |
2246 | SemaRef.Diag( |
2247 | Dcl->getLocation(), |
2248 | SemaRef.getLangOpts().CPlusPlus20 |
2249 | ? diag::warn_cxx17_compat_constexpr_union_ctor_no_init |
2250 | : diag::ext_constexpr_union_ctor_no_init); |
2251 | } else if (!SemaRef.getLangOpts().CPlusPlus20) { |
2252 | return false; |
2253 | } |
2254 | } |
2255 | } else if (!Constructor->isDependentContext() && |
2256 | !Constructor->isDelegatingConstructor()) { |
2257 | assert(RD->getNumVBases() == 0 && "constexpr ctor with virtual bases"); |
2258 | |
2259 | |
2260 | |
2261 | bool AnyAnonStructUnionMembers = false; |
2262 | unsigned Fields = 0; |
2263 | for (CXXRecordDecl::field_iterator I = RD->field_begin(), |
2264 | E = RD->field_end(); I != E; ++I, ++Fields) { |
2265 | if (I->isAnonymousStructOrUnion()) { |
2266 | AnyAnonStructUnionMembers = true; |
2267 | break; |
2268 | } |
2269 | } |
2270 | |
2271 | |
2272 | |
2273 | |
2274 | if (AnyAnonStructUnionMembers || |
2275 | Constructor->getNumCtorInitializers() != RD->getNumBases() + Fields) { |
2276 | |
2277 | |
2278 | |
2279 | llvm::SmallSet<Decl*, 16> Inits; |
2280 | for (const auto *I: Constructor->inits()) { |
2281 | if (FieldDecl *FD = I->getMember()) |
2282 | Inits.insert(FD); |
2283 | else if (IndirectFieldDecl *ID = I->getIndirectMember()) |
2284 | Inits.insert(ID->chain_begin(), ID->chain_end()); |
2285 | } |
2286 | |
2287 | bool Diagnosed = false; |
2288 | for (auto *I : RD->fields()) |
2289 | if (!CheckConstexprCtorInitializer(SemaRef, Dcl, I, Inits, Diagnosed, |
2290 | Kind)) |
2291 | return false; |
2292 | } |
2293 | } |
2294 | } else { |
2295 | if (ReturnStmts.empty()) { |
2296 | |
2297 | |
2298 | |
2299 | |
2300 | bool OK = SemaRef.getLangOpts().CPlusPlus14 && |
2301 | (Dcl->getReturnType()->isVoidType() || |
2302 | Dcl->getReturnType()->isDependentType()); |
2303 | switch (Kind) { |
2304 | case Sema::CheckConstexprKind::Diagnose: |
2305 | SemaRef.Diag(Dcl->getLocation(), |
2306 | OK ? diag::warn_cxx11_compat_constexpr_body_no_return |
2307 | : diag::err_constexpr_body_no_return) |
2308 | << Dcl->isConsteval(); |
2309 | if (!OK) |
2310 | return false; |
2311 | break; |
2312 | |
2313 | case Sema::CheckConstexprKind::CheckValid: |
2314 | |
2315 | |
2316 | |
2317 | if (!SemaRef.getLangOpts().CPlusPlus14) |
2318 | return false; |
2319 | break; |
2320 | } |
2321 | } else if (ReturnStmts.size() > 1) { |
2322 | switch (Kind) { |
2323 | case Sema::CheckConstexprKind::Diagnose: |
2324 | SemaRef.Diag( |
2325 | ReturnStmts.back(), |
2326 | SemaRef.getLangOpts().CPlusPlus14 |
2327 | ? diag::warn_cxx11_compat_constexpr_body_multiple_return |
2328 | : diag::ext_constexpr_body_multiple_return); |
2329 | for (unsigned I = 0; I < ReturnStmts.size() - 1; ++I) |
2330 | SemaRef.Diag(ReturnStmts[I], |
2331 | diag::note_constexpr_body_previous_return); |
2332 | break; |
2333 | |
2334 | case Sema::CheckConstexprKind::CheckValid: |
2335 | if (!SemaRef.getLangOpts().CPlusPlus14) |
2336 | return false; |
2337 | break; |
2338 | } |
2339 | } |
2340 | } |
2341 | |
2342 | |
2343 | |
2344 | |
2345 | |
2346 | |
2347 | |
2348 | |
2349 | |
2350 | |
2351 | |
2352 | |
2353 | |
2354 | |
2355 | SmallVector<PartialDiagnosticAt, 8> Diags; |
2356 | if (Kind == Sema::CheckConstexprKind::Diagnose && |
2357 | !Expr::isPotentialConstantExpr(Dcl, Diags)) { |
2358 | SemaRef.Diag(Dcl->getLocation(), |
2359 | diag::ext_constexpr_function_never_constant_expr) |
2360 | << isa<CXXConstructorDecl>(Dcl) << Dcl->isConsteval(); |
2361 | for (size_t I = 0, N = Diags.size(); I != N; ++I) |
2362 | SemaRef.Diag(Diags[I].first, Diags[I].second); |
2363 | |
2364 | |
2365 | } |
2366 | |
2367 | return true; |
2368 | } |
2369 | |
2370 | |
2371 | |
2372 | |
2373 | |
2374 | |
2375 | |
2376 | |
2377 | |
2378 | CXXRecordDecl *Sema::getCurrentClass(Scope *, const CXXScopeSpec *SS) { |
2379 | assert(getLangOpts().CPlusPlus && "No class names in C!"); |
2380 | |
2381 | if (SS && SS->isInvalid()) |
2382 | return nullptr; |
2383 | |
2384 | if (SS && SS->isNotEmpty()) { |
2385 | DeclContext *DC = computeDeclContext(*SS, true); |
2386 | return dyn_cast_or_null<CXXRecordDecl>(DC); |
2387 | } |
2388 | |
2389 | return dyn_cast_or_null<CXXRecordDecl>(CurContext); |
2390 | } |
2391 | |
2392 | |
2393 | |
2394 | |
2395 | |
2396 | bool Sema::isCurrentClassName(const IdentifierInfo &II, Scope *S, |
2397 | const CXXScopeSpec *SS) { |
2398 | CXXRecordDecl *CurDecl = getCurrentClass(S, SS); |
2399 | return CurDecl && &II == CurDecl->getIdentifier(); |
2400 | } |
2401 | |
2402 | |
2403 | |
2404 | |
2405 | bool Sema::isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS) { |
2406 | assert(getLangOpts().CPlusPlus && "No class names in C!"); |
2407 | |
2408 | if (!getLangOpts().SpellChecking) |
2409 | return false; |
2410 | |
2411 | CXXRecordDecl *CurDecl; |
2412 | if (SS && SS->isSet() && !SS->isInvalid()) { |
2413 | DeclContext *DC = computeDeclContext(*SS, true); |
2414 | CurDecl = dyn_cast_or_null<CXXRecordDecl>(DC); |
2415 | } else |
2416 | CurDecl = dyn_cast_or_null<CXXRecordDecl>(CurContext); |
2417 | |
2418 | if (CurDecl && CurDecl->getIdentifier() && II != CurDecl->getIdentifier() && |
2419 | 3 * II->getName().edit_distance(CurDecl->getIdentifier()->getName()) |
2420 | < II->getLength()) { |
2421 | II = CurDecl->getIdentifier(); |
2422 | return true; |
2423 | } |
2424 | |
2425 | return false; |
2426 | } |
2427 | |
2428 | |
2429 | |
2430 | static bool findCircularInheritance(const CXXRecordDecl *Class, |
2431 | const CXXRecordDecl *Current) { |
2432 | SmallVector<const CXXRecordDecl*, 8> Queue; |
2433 | |
2434 | Class = Class->getCanonicalDecl(); |
2435 | while (true) { |
2436 | for (const auto &I : Current->bases()) { |
2437 | CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl(); |
2438 | if (!Base) |
2439 | continue; |
2440 | |
2441 | Base = Base->getDefinition(); |
2442 | if (!Base) |
2443 | continue; |
2444 | |
2445 | if (Base->getCanonicalDecl() == Class) |
2446 | return true; |
2447 | |
2448 | Queue.push_back(Base); |
2449 | } |
2450 | |
2451 | if (Queue.empty()) |
2452 | return false; |
2453 | |
2454 | Current = Queue.pop_back_val(); |
2455 | } |
2456 | |
2457 | return false; |
2458 | } |
2459 | |
2460 | |
2461 | |
2462 | |
2463 | |
2464 | CXXBaseSpecifier * |
2465 | Sema::CheckBaseSpecifier(CXXRecordDecl *Class, |
2466 | SourceRange SpecifierRange, |
2467 | bool Virtual, AccessSpecifier Access, |
2468 | TypeSourceInfo *TInfo, |
2469 | SourceLocation EllipsisLoc) { |
2470 | QualType BaseType = TInfo->getType(); |
2471 | if (BaseType->containsErrors()) { |
2472 | |
2473 | return nullptr; |
2474 | } |
2475 | |
2476 | |
2477 | if (Class->isUnion()) { |
2478 | Diag(Class->getLocation(), diag::err_base_clause_on_union) |
2479 | << SpecifierRange; |
2480 | return nullptr; |
2481 | } |
2482 | |
2483 | if (EllipsisLoc.isValid() && |
2484 | !TInfo->getType()->containsUnexpandedParameterPack()) { |
2485 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) |
2486 | << TInfo->getTypeLoc().getSourceRange(); |
2487 | EllipsisLoc = SourceLocation(); |
2488 | } |
2489 | |
2490 | SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc(); |
2491 | |
2492 | if (BaseType->isDependentType()) { |
2493 | |
2494 | |
2495 | |
2496 | if (CXXRecordDecl *BaseDecl = BaseType->getAsCXXRecordDecl()) { |
2497 | if (BaseDecl->getCanonicalDecl() == Class->getCanonicalDecl() || |
2498 | ((BaseDecl = BaseDecl->getDefinition()) && |
2499 | findCircularInheritance(Class, BaseDecl))) { |
2500 | Diag(BaseLoc, diag::err_circular_inheritance) |
2501 | << BaseType << Context.getTypeDeclType(Class); |
2502 | |
2503 | if (BaseDecl->getCanonicalDecl() != Class->getCanonicalDecl()) |
2504 | Diag(BaseDecl->getLocation(), diag::note_previous_decl) |
2505 | << BaseType; |
2506 | |
2507 | return nullptr; |
2508 | } |
2509 | } |
2510 | |
2511 | |
2512 | |
2513 | |
2514 | |
2515 | |
2516 | |
2517 | if (!Class->getTypeForDecl()->isDependentType()) |
2518 | Class->setInvalidDecl(); |
2519 | return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, |
2520 | Class->getTagKind() == TTK_Class, |
2521 | Access, TInfo, EllipsisLoc); |
2522 | } |
2523 | |
2524 | |
2525 | if (!BaseType->isRecordType()) { |
2526 | Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange; |
2527 | return nullptr; |
2528 | } |
2529 | |
2530 | |
2531 | |
2532 | if (BaseType->isUnionType()) { |
2533 | Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange; |
2534 | return nullptr; |
2535 | } |
2536 | |
2537 | |
2538 | if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { |
2539 | if (Attr *ClassAttr = getDLLAttr(Class)) { |
2540 | if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>( |
2541 | BaseType->getAsCXXRecordDecl())) { |
2542 | propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseTemplate, |
2543 | BaseLoc); |
2544 | } |
2545 | } |
2546 | } |
2547 | |
2548 | |
2549 | |
2550 | |
2551 | if (RequireCompleteType(BaseLoc, BaseType, |
2552 | diag::err_incomplete_base_class, SpecifierRange)) { |
2553 | Class->setInvalidDecl(); |
2554 | return nullptr; |
2555 | } |
2556 | |
2557 | |
2558 | RecordDecl *BaseDecl = BaseType->castAs<RecordType>()->getDecl(); |
2559 | assert(BaseDecl && "Record type has no declaration"); |
2560 | BaseDecl = BaseDecl->getDefinition(); |
2561 | assert(BaseDecl && "Base type is not incomplete, but has no definition"); |
2562 | CXXRecordDecl *CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl); |
2563 | assert(CXXBaseDecl && "Base type is not a C++ type"); |
2564 | |
2565 | |
2566 | |
2567 | |
2568 | const auto *BaseCSA = CXXBaseDecl->getAttr<CodeSegAttr>(); |
2569 | const auto *DerivedCSA = Class->getAttr<CodeSegAttr>(); |
2570 | if ((DerivedCSA || BaseCSA) && |
2571 | (!BaseCSA || !DerivedCSA || BaseCSA->getName() != DerivedCSA->getName())) { |
2572 | Diag(Class->getLocation(), diag::err_mismatched_code_seg_base); |
2573 | Diag(CXXBaseDecl->getLocation(), diag::note_base_class_specified_here) |
2574 | << CXXBaseDecl; |
2575 | return nullptr; |
2576 | } |
2577 | |
2578 | |
2579 | |
2580 | |
2581 | |
2582 | |
2583 | |
2584 | if (CXXBaseDecl->hasFlexibleArrayMember()) { |
2585 | Diag(BaseLoc, diag::err_base_class_has_flexible_array_member) |
2586 | << CXXBaseDecl->getDeclName(); |
2587 | return nullptr; |
2588 | } |
2589 | |
2590 | |
2591 | |
2592 | |
2593 | if (FinalAttr *FA = CXXBaseDecl->getAttr<FinalAttr>()) { |
2594 | Diag(BaseLoc, diag::err_class_marked_final_used_as_base) |
2595 | << CXXBaseDecl->getDeclName() |
2596 | << FA->isSpelledAsSealed(); |
2597 | Diag(CXXBaseDecl->getLocation(), diag::note_entity_declared_at) |
2598 | << CXXBaseDecl->getDeclName() << FA->getRange(); |
2599 | return nullptr; |
2600 | } |
2601 | |
2602 | if (BaseDecl->isInvalidDecl()) |
2603 | Class->setInvalidDecl(); |
2604 | |
2605 | |
2606 | return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, |
2607 | Class->getTagKind() == TTK_Class, |
2608 | Access, TInfo, EllipsisLoc); |
2609 | } |
2610 | |
2611 | |
2612 | |
2613 | |
2614 | |
2615 | |
2616 | BaseResult |
2617 | Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange, |
2618 | ParsedAttributes &Attributes, |
2619 | bool Virtual, AccessSpecifier Access, |
2620 | ParsedType basetype, SourceLocation BaseLoc, |
2621 | SourceLocation EllipsisLoc) { |
2622 | if (!classdecl) |
2623 | return true; |
2624 | |
2625 | AdjustDeclIfTemplate(classdecl); |
2626 | CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(classdecl); |
2627 | if (!Class) |
2628 | return true; |
2629 | |
2630 | |
2631 | Class->setIsParsingBaseSpecifiers(); |
2632 | |
2633 | |
2634 | |
2635 | for (const ParsedAttr &AL : Attributes) { |
2636 | if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute) |
2637 | continue; |
2638 | Diag(AL.getLoc(), AL.getKind() == ParsedAttr::UnknownAttribute |
2639 | ? (unsigned)diag::warn_unknown_attribute_ignored |
2640 | : (unsigned)diag::err_base_specifier_attribute) |
2641 | << AL << AL.getRange(); |
2642 | } |
2643 | |
2644 | TypeSourceInfo *TInfo = nullptr; |
2645 | GetTypeFromParser(basetype, &TInfo); |
2646 | |
2647 | if (EllipsisLoc.isInvalid() && |
2648 | DiagnoseUnexpandedParameterPack(SpecifierRange.getBegin(), TInfo, |
2649 | UPPC_BaseType)) |
2650 | return true; |
2651 | |
2652 | if (CXXBaseSpecifier *BaseSpec = CheckBaseSpecifier(Class, SpecifierRange, |
2653 | Virtual, Access, TInfo, |
2654 | EllipsisLoc)) |
2655 | return BaseSpec; |
2656 | else |
2657 | Class->setInvalidDecl(); |
2658 | |
2659 | return true; |
2660 | } |
2661 | |
2662 | |
2663 | |
2664 | typedef llvm::SmallPtrSet<QualType, 4> IndirectBaseSet; |
2665 | |
2666 | |
2667 | static void |
2668 | NoteIndirectBases(ASTContext &Context, IndirectBaseSet &Set, |
2669 | const QualType &Type) |
2670 | { |
2671 | |
2672 | |
2673 | if (auto Rec = Type->getAs<RecordType>()) { |
2674 | auto Decl = Rec->getAsCXXRecordDecl(); |
2675 | |
2676 | |
2677 | for (const auto &BaseSpec : Decl->bases()) { |
2678 | QualType Base = Context.getCanonicalType(BaseSpec.getType()) |
2679 | .getUnqualifiedType(); |
2680 | if (Set.insert(Base).second) |
2681 | |
2682 | NoteIndirectBases(Context, Set, Base); |
2683 | } |
2684 | } |
2685 | } |
2686 | |
2687 | |
2688 | |
2689 | bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, |
2690 | MutableArrayRef<CXXBaseSpecifier *> Bases) { |
2691 | if (Bases.empty()) |
2692 | return false; |
2693 | |
2694 | |
2695 | |
2696 | |
2697 | |
2698 | std::map<QualType, CXXBaseSpecifier*, QualTypeOrdering> KnownBaseTypes; |
2699 | |
2700 | |
2701 | |
2702 | IndirectBaseSet IndirectBaseTypes; |
2703 | |
2704 | |
2705 | unsigned NumGoodBases = 0; |
2706 | bool Invalid = false; |
2707 | for (unsigned idx = 0; idx < Bases.size(); ++idx) { |
2708 | QualType NewBaseType |
2709 | = Context.getCanonicalType(Bases[idx]->getType()); |
2710 | NewBaseType = NewBaseType.getLocalUnqualifiedType(); |
2711 | |
2712 | CXXBaseSpecifier *&KnownBase = KnownBaseTypes[NewBaseType]; |
2713 | if (KnownBase) { |
2714 | |
2715 | |
2716 | |
2717 | Diag(Bases[idx]->getBeginLoc(), diag::err_duplicate_base_class) |
2718 | << KnownBase->getType() << Bases[idx]->getSourceRange(); |
2719 | |
2720 | |
2721 | |
2722 | Context.Deallocate(Bases[idx]); |
2723 | |
2724 | Invalid = true; |
2725 | } else { |
2726 | |
2727 | KnownBase = Bases[idx]; |
2728 | Bases[NumGoodBases++] = Bases[idx]; |
2729 | |
2730 | |
2731 | if (Bases.size() > 1) |
2732 | NoteIndirectBases(Context, IndirectBaseTypes, NewBaseType); |
2733 | |
2734 | if (const RecordType *Record = NewBaseType->getAs<RecordType>()) { |
2735 | const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); |
2736 | if (Class->isInterface() && |
2737 | (!RD->isInterfaceLike() || |
2738 | KnownBase->getAccessSpecifier() != AS_public)) { |
2739 | |
2740 | |
2741 | Diag(KnownBase->getBeginLoc(), diag::err_invalid_base_in_interface) |
2742 | << getRecordDiagFromTagKind(RD->getTagKind()) << RD |
2743 | << RD->getSourceRange(); |
2744 | Invalid = true; |
2745 | } |
2746 | if (RD->hasAttr<WeakAttr>()) |
2747 | Class->addAttr(WeakAttr::CreateImplicit(Context)); |
2748 | } |
2749 | } |
2750 | } |
2751 | |
2752 | |
2753 | Class->setBases(Bases.data(), NumGoodBases); |
2754 | |
2755 | |
2756 | for (unsigned idx = 0; idx < NumGoodBases; ++idx) { |
2757 | |
2758 | QualType BaseType = Bases[idx]->getType(); |
2759 | |
2760 | |
2761 | |
2762 | if (BaseType->isDependentType()) |
2763 | continue; |
2764 | |
2765 | CanQualType CanonicalBase = Context.getCanonicalType(BaseType) |
2766 | .getUnqualifiedType(); |
2767 | |
2768 | if (IndirectBaseTypes.count(CanonicalBase)) { |
2769 | CXXBasePaths Paths(true, true, |
2770 | true); |
2771 | bool found |
2772 | = Class->isDerivedFrom(CanonicalBase->getAsCXXRecordDecl(), Paths); |
2773 | assert(found); |
2774 | (void)found; |
2775 | |
2776 | if (Paths.isAmbiguous(CanonicalBase)) |
2777 | Diag(Bases[idx]->getBeginLoc(), diag::warn_inaccessible_base_class) |
2778 | << BaseType << getAmbiguousPathsDisplayString(Paths) |
2779 | << Bases[idx]->getSourceRange(); |
2780 | else |
2781 | assert(Bases[idx]->isVirtual()); |
2782 | } |
2783 | |
2784 | |
2785 | |
2786 | Context.Deallocate(Bases[idx]); |
2787 | } |
2788 | |
2789 | return Invalid; |
2790 | } |
2791 | |
2792 | |
2793 | |
2794 | |
2795 | void Sema::ActOnBaseSpecifiers(Decl *ClassDecl, |
2796 | MutableArrayRef<CXXBaseSpecifier *> Bases) { |
2797 | if (!ClassDecl || Bases.empty()) |
2798 | return; |
2799 | |
2800 | AdjustDeclIfTemplate(ClassDecl); |
2801 | AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl), Bases); |
2802 | } |
2803 | |
2804 | |
2805 | |
2806 | bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) { |
2807 | if (!getLangOpts().CPlusPlus) |
2808 | return false; |
2809 | |
2810 | CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl(); |
2811 | if (!DerivedRD) |
2812 | return false; |
2813 | |
2814 | CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl(); |
2815 | if (!BaseRD) |
2816 | return false; |
2817 | |
2818 | |
2819 | |
2820 | if (BaseRD->isInvalidDecl() || DerivedRD->isInvalidDecl()) |
2821 | return false; |
2822 | |
2823 | |
2824 | |
2825 | if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined()) |
2826 | return false; |
2827 | |
2828 | return DerivedRD->isDerivedFrom(BaseRD); |
2829 | } |
2830 | |
2831 | |
2832 | |
2833 | bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base, |
2834 | CXXBasePaths &Paths) { |
2835 | if (!getLangOpts().CPlusPlus) |
2836 | return false; |
2837 | |
2838 | CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl(); |
2839 | if (!DerivedRD) |
2840 | return false; |
2841 | |
2842 | CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl(); |
2843 | if (!BaseRD) |
2844 | return false; |
2845 | |
2846 | if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined()) |
2847 | return false; |
2848 | |
2849 | return DerivedRD->isDerivedFrom(BaseRD, Paths); |
2850 | } |
2851 | |
2852 | static void BuildBasePathArray(const CXXBasePath &Path, |
2853 | CXXCastPath &BasePathArray) { |
2854 | |
2855 | |
2856 | |
2857 | unsigned Start = 0; |
2858 | for (unsigned I = Path.size(); I != 0; --I) { |
2859 | if (Path[I - 1].Base->isVirtual()) { |
2860 | Start = I - 1; |
2861 | break; |
2862 | } |
2863 | } |
2864 | |
2865 | |
2866 | for (unsigned I = Start, E = Path.size(); I != E; ++I) |
2867 | BasePathArray.push_back(const_cast<CXXBaseSpecifier*>(Path[I].Base)); |
2868 | } |
2869 | |
2870 | |
2871 | void Sema::BuildBasePathArray(const CXXBasePaths &Paths, |
2872 | CXXCastPath &BasePathArray) { |
2873 | assert(BasePathArray.empty() && "Base path array must be empty!"); |
2874 | assert(Paths.isRecordingPaths() && "Must record paths!"); |
2875 | return ::BuildBasePathArray(Paths.front(), BasePathArray); |
2876 | } |
2877 | |
2878 | |
2879 | |
2880 | |
2881 | |
2882 | |
2883 | |
2884 | |
2885 | |
2886 | |
2887 | |
2888 | |
2889 | bool |
2890 | Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, |
2891 | unsigned InaccessibleBaseID, |
2892 | unsigned AmbiguousBaseConvID, |
2893 | SourceLocation Loc, SourceRange Range, |
2894 | DeclarationName Name, |
2895 | CXXCastPath *BasePath, |
2896 | bool IgnoreAccess) { |
2897 | |
2898 | |
2899 | |
2900 | |
2901 | CXXBasePaths Paths(true, true, |
2902 | false); |
2903 | bool DerivationOkay = IsDerivedFrom(Loc, Derived, Base, Paths); |
2904 | if (!DerivationOkay) |
2905 | return true; |
2906 | |
2907 | const CXXBasePath *Path = nullptr; |
2908 | if (!Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) |
2909 | Path = &Paths.front(); |
2910 | |
2911 | |
2912 | |
2913 | |
2914 | if (!Path && getLangOpts().MSVCCompat) { |
2915 | for (const CXXBasePath &PossiblePath : Paths) { |
2916 | if (PossiblePath.size() == 1) { |
2917 | Path = &PossiblePath; |
2918 | if (AmbiguousBaseConvID) |
2919 | Diag(Loc, diag::ext_ms_ambiguous_direct_base) |
2920 | << Base << Derived << Range; |
2921 | break; |
2922 | } |
2923 | } |
2924 | } |
2925 | |
2926 | if (Path) { |
2927 | if (!IgnoreAccess) { |
2928 | |
2929 | switch ( |
2930 | CheckBaseClassAccess(Loc, Base, Derived, *Path, InaccessibleBaseID)) { |
2931 | case AR_inaccessible: |
2932 | return true; |
2933 | case AR_accessible: |
2934 | case AR_dependent: |
2935 | case AR_delayed: |
2936 | break; |
2937 | } |
2938 | } |
2939 | |
2940 | |
2941 | if (BasePath) |
2942 | ::BuildBasePathArray(*Path, *BasePath); |
2943 | return false; |
2944 | } |
2945 | |
2946 | if (AmbiguousBaseConvID) { |
2947 | |
2948 | |
2949 | |
2950 | |
2951 | |
2952 | |
2953 | Paths.clear(); |
2954 | Paths.setRecordingPaths(true); |
2955 | bool StillOkay = IsDerivedFrom(Loc, Derived, Base, Paths); |
2956 | assert(StillOkay && "Can only be used with a derived-to-base conversion"); |
2957 | (void)StillOkay; |
2958 | |
2959 | |
2960 | |
2961 | |
2962 | |
2963 | std::string PathDisplayStr = getAmbiguousPathsDisplayString(Paths); |
2964 | |
2965 | Diag(Loc, AmbiguousBaseConvID) |
2966 | << Derived << Base << PathDisplayStr << Range << Name; |
2967 | } |
2968 | return true; |
2969 | } |
2970 | |
2971 | bool |
2972 | Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, |
2973 | SourceLocation Loc, SourceRange Range, |
2974 | CXXCastPath *BasePath, |
2975 | bool IgnoreAccess) { |
2976 | return CheckDerivedToBaseConversion( |
2977 | Derived, Base, diag::err_upcast_to_inaccessible_base, |
2978 | diag::err_ambiguous_derived_to_base_conv, Loc, Range, DeclarationName(), |
2979 | BasePath, IgnoreAccess); |
2980 | } |
2981 | |
2982 | |
2983 | |
2984 | |
2985 | |
2986 | |
2987 | |
2988 | |
2989 | |
2990 | |
2991 | |
2992 | |
2993 | |
2994 | |
2995 | std::string Sema::getAmbiguousPathsDisplayString(CXXBasePaths &Paths) { |
2996 | std::string PathDisplayStr; |
2997 | std::set<unsigned> DisplayedPaths; |
2998 | for (CXXBasePaths::paths_iterator Path = Paths.begin(); |
2999 | Path != Paths.end(); ++Path) { |
3000 | if (DisplayedPaths.insert(Path->back().SubobjectNumber).second) { |
3001 | |
3002 | |
3003 | PathDisplayStr += "\n "; |
3004 | PathDisplayStr += Context.getTypeDeclType(Paths.getOrigin()).getAsString(); |
3005 | for (CXXBasePath::const_iterator Element = Path->begin(); |
3006 | Element != Path->end(); ++Element) |
3007 | PathDisplayStr += " -> " + Element->Base->getType().getAsString(); |
3008 | } |
3009 | } |
3010 | |
3011 | return PathDisplayStr; |
3012 | } |
3013 | |
3014 | |
3015 | |
3016 | |
3017 | |
3018 | |
3019 | bool Sema::ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc, |
3020 | SourceLocation ColonLoc, |
3021 | const ParsedAttributesView &Attrs) { |
3022 | assert(Access != AS_none && "Invalid kind for syntactic access specifier!"); |
3023 | AccessSpecDecl *ASDecl = AccessSpecDecl::Create(Context, Access, CurContext, |
3024 | ASLoc, ColonLoc); |
3025 | CurContext->addHiddenDecl(ASDecl); |
3026 | return ProcessAccessDeclAttributeList(ASDecl, Attrs); |
3027 | } |
3028 | |
3029 | |
3030 | void Sema::CheckOverrideControl(NamedDecl *D) { |
3031 | if (D->isInvalidDecl()) |
3032 | return; |
3033 | |
3034 | |
3035 | if (!D->hasAttr<OverrideAttr>() && !D->hasAttr<FinalAttr>()) |
3036 | return; |
3037 | |
3038 | CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D); |
3039 | |
3040 | |
3041 | if (MD && MD->isInstance() && |
3042 | (MD->getParent()->hasAnyDependentBases() || |
3043 | MD->getType()->isDependentType())) |
3044 | return; |
3045 | |
3046 | if (MD && !MD->isVirtual()) { |
3047 | |
3048 | |
3049 | SmallVector<CXXMethodDecl *, 8> OverloadedMethods; |
3050 | FindHiddenVirtualMethods(MD, OverloadedMethods); |
3051 | |
3052 | if (!OverloadedMethods.empty()) { |
3053 | if (OverrideAttr *OA = D->getAttr<OverrideAttr>()) { |
3054 | Diag(OA->getLocation(), |
3055 | diag::override_keyword_hides_virtual_member_function) |
3056 | << "override" << (OverloadedMethods.size() > 1); |
3057 | } else if (FinalAttr *FA = D->getAttr<FinalAttr>()) { |
3058 | Diag(FA->getLocation(), |
3059 | diag::override_keyword_hides_virtual_member_function) |
3060 | << (FA->isSpelledAsSealed() ? "sealed" : "final") |
3061 | << (OverloadedMethods.size() > 1); |
3062 | } |
3063 | NoteHiddenVirtualMethods(MD, OverloadedMethods); |
3064 | MD->setInvalidDecl(); |
3065 | return; |
3066 | } |
3067 | |
3068 | |
3069 | } |
3070 | |
3071 | if (!MD || !MD->isVirtual()) { |
3072 | if (OverrideAttr *OA = D->getAttr<OverrideAttr>()) { |
3073 | Diag(OA->getLocation(), |
3074 | diag::override_keyword_only_allowed_on_virtual_member_functions) |
3075 | << "override" << FixItHint::CreateRemoval(OA->getLocation()); |
3076 | D->dropAttr<OverrideAttr>(); |
3077 | } |
3078 | if (FinalAttr *FA = D->getAttr<FinalAttr>()) { |
3079 | Diag(FA->getLocation(), |
3080 | diag::override_keyword_only_allowed_on_virtual_member_functions) |
3081 | << (FA->isSpelledAsSealed() ? "sealed" : "final") |
3082 | << FixItHint::CreateRemoval(FA->getLocation()); |
3083 | D->dropAttr<FinalAttr>(); |
3084 | } |
3085 | return; |
3086 | } |
3087 | |
3088 | |
3089 | |
3090 | |
3091 | |
3092 | bool HasOverriddenMethods = MD->size_overridden_methods() != 0; |
3093 | if (MD->hasAttr<OverrideAttr>() && !HasOverriddenMethods) |
3094 | Diag(MD->getLocation(), diag::err_function_marked_override_not_overriding) |
3095 | << MD->getDeclName(); |
3096 | } |
3097 | |
3098 | void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent) { |
3099 | if (D->isInvalidDecl() || D->hasAttr<OverrideAttr>()) |
3100 | return; |
3101 | CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D); |
3102 | if (!MD || MD->isImplicit() || MD->hasAttr<FinalAttr>()) |
3103 | return; |
3104 | |
3105 | SourceLocation Loc = MD->getLocation(); |
3106 | SourceLocation SpellingLoc = Loc; |
3107 | if (getSourceManager().isMacroArgExpansion(Loc)) |
3108 | SpellingLoc = getSourceManager().getImmediateExpansionRange(Loc).getBegin(); |
3109 | SpellingLoc = getSourceManager().getSpellingLoc(SpellingLoc); |
3110 | if (SpellingLoc.isValid() && getSourceManager().isInSystemHeader(SpellingLoc)) |
3111 | return; |
3112 | |
3113 | if (MD->size_overridden_methods() > 0) { |
3114 | auto EmitDiag = [&](unsigned DiagInconsistent, unsigned DiagSuggest) { |
3115 | unsigned DiagID = |
3116 | Inconsistent && !Diags.isIgnored(DiagInconsistent, MD->getLocation()) |
3117 | ? DiagInconsistent |
3118 | : DiagSuggest; |
3119 | Diag(MD->getLocation(), DiagID) << MD->getDeclName(); |
3120 | const CXXMethodDecl *OMD = *MD->begin_overridden_methods(); |
3121 | Diag(OMD->getLocation(), diag::note_overridden_virtual_function); |
3122 | }; |
3123 | if (isa<CXXDestructorDecl>(MD)) |
3124 | EmitDiag( |
3125 | diag::warn_inconsistent_destructor_marked_not_override_overriding, |
3126 | diag::warn_suggest_destructor_marked_not_override_overriding); |
3127 | else |
3128 | EmitDiag(diag::warn_inconsistent_function_marked_not_override_overriding, |
3129 | diag::warn_suggest_function_marked_not_override_overriding); |
3130 | } |
3131 | } |
3132 | |
3133 | |
3134 | |
3135 | |
3136 | bool Sema::CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New, |
3137 | const CXXMethodDecl *Old) { |
3138 | FinalAttr *FA = Old->getAttr<FinalAttr>(); |
3139 | if (!FA) |
3140 | return false; |
3141 | |
3142 | Diag(New->getLocation(), diag::err_final_function_overridden) |
3143 | << New->getDeclName() |
3144 | << FA->isSpelledAsSealed(); |
3145 | Diag(Old->getLocation(), diag::note_overridden_virtual_function); |
3146 | return true; |
3147 | } |
3148 | |
3149 | static bool InitializationHasSideEffects(const FieldDecl &FD) { |
3150 | const Type *T = FD.getType()->getBaseElementTypeUnsafe(); |
3151 | |
3152 | if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) |
3153 | return !RD->isCompleteDefinition() || |
3154 | !RD->hasTrivialDefaultConstructor() || |
3155 | !RD->hasTrivialDestructor(); |
3156 | return false; |
3157 | } |
3158 | |
3159 | static const ParsedAttr *getMSPropertyAttr(const ParsedAttributesView &list) { |
3160 | ParsedAttributesView::const_iterator Itr = |
3161 | llvm::find_if(list, [](const ParsedAttr &AL) { |
3162 | return AL.isDeclspecPropertyAttribute(); |
3163 | }); |
3164 | if (Itr != list.end()) |
3165 | return &*Itr; |
3166 | return nullptr; |
3167 | } |
3168 | |
3169 | |
3170 | void Sema::CheckShadowInheritedFields(const SourceLocation &Loc, |
3171 | DeclarationName FieldName, |
3172 | const CXXRecordDecl *RD, |
3173 | bool DeclIsField) { |
3174 | if (Diags.isIgnored(diag::warn_shadow_field, Loc)) |
3175 | return; |
3176 | |
3177 | |
3178 | std::map<CXXRecordDecl*, NamedDecl*> Bases; |
3179 | auto FieldShadowed = [&](const CXXBaseSpecifier *Specifier, |
3180 | CXXBasePath &Path) { |
3181 | const auto Base = Specifier->getType()->getAsCXXRecordDecl(); |
3182 | |
3183 | if (Bases.find(Base) != Bases.end()) |
3184 | return true; |
3185 | for (const auto Field : Base->lookup(FieldName)) { |
3186 | if ((isa<FieldDecl>(Field) || isa<IndirectFieldDecl>(Field)) && |
3187 | Field->getAccess() != AS_private) { |
3188 | assert(Field->getAccess() != AS_none); |
3189 | assert(Bases.find(Base) == Bases.end()); |
3190 | Bases[Base] = Field; |
3191 | return true; |
3192 | } |
3193 | } |
3194 | return false; |
3195 | }; |
3196 | |
3197 | CXXBasePaths Paths(true, true, |
3198 | true); |
3199 | if (!RD->lookupInBases(FieldShadowed, Paths)) |
3200 | return; |
3201 | |
3202 | for (const auto &P : Paths) { |
3203 | auto Base = P.back().Base->getType()->getAsCXXRecordDecl(); |
3204 | auto It = Bases.find(Base); |
3205 | |
3206 | if (It == Bases.end()) |
3207 | continue; |
3208 | auto BaseField = It->second; |
3209 | assert(BaseField->getAccess() != AS_private); |
3210 | if (AS_none != |
3211 | CXXRecordDecl::MergeAccess(P.Access, BaseField->getAccess())) { |
3212 | Diag(Loc, diag::warn_shadow_field) |
3213 | << FieldName << RD << Base << DeclIsField; |
3214 | Diag(BaseField->getLocation(), diag::note_shadow_field); |
3215 | Bases.erase(It); |
3216 | } |
3217 | } |
3218 | } |
3219 | |
3220 | |
3221 | |
3222 | |
3223 | |
3224 | |
3225 | NamedDecl * |
3226 | Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, |
3227 | MultiTemplateParamsArg TemplateParameterLists, |
3228 | Expr *BW, const VirtSpecifiers &VS, |
3229 | InClassInitStyle InitStyle) { |
3230 | const DeclSpec &DS = D.getDeclSpec(); |
3231 | DeclarationNameInfo NameInfo = GetNameForDeclarator(D); |
3232 | DeclarationName Name = NameInfo.getName(); |
3233 | SourceLocation Loc = NameInfo.getLoc(); |
3234 | |
3235 | |
3236 | if (Loc.isInvalid()) |
3237 | Loc = D.getBeginLoc(); |
3238 | |
3239 | Expr *BitWidth = static_cast<Expr*>(BW); |
3240 | |
3241 | assert(isa<CXXRecordDecl>(CurContext)); |
3242 | assert(!DS.isFriendSpecified()); |
3243 | |
3244 | bool isFunc = D.isDeclarationOfFunction(); |
3245 | const ParsedAttr *MSPropertyAttr = |
3246 | getMSPropertyAttr(D.getDeclSpec().getAttributes()); |
3247 | |
3248 | if (cast<CXXRecordDecl>(CurContext)->isInterface()) { |
3249 | |
3250 | |
3251 | |
3252 | unsigned InvalidDecl; |
3253 | bool ShowDeclName = true; |
3254 | if (!isFunc && |
3255 | (DS.getStorageClassSpec() == DeclSpec::SCS_typedef || MSPropertyAttr)) |
3256 | InvalidDecl = 0; |
3257 | else if (!isFunc) |
3258 | InvalidDecl = 1; |
3259 | else if (AS != AS_public) |
3260 | InvalidDecl = 2; |
3261 | else if (DS.getStorageClassSpec() == DeclSpec::SCS_static) |
3262 | InvalidDecl = 3; |
3263 | else switch (Name.getNameKind()) { |
3264 | case DeclarationName::CXXConstructorName: |
3265 | InvalidDecl = 4; |
3266 | ShowDeclName = false; |
3267 | break; |
3268 | |
3269 | case DeclarationName::CXXDestructorName: |
3270 | InvalidDecl = 5; |
3271 | ShowDeclName = false; |
3272 | break; |
3273 | |
3274 | case DeclarationName::CXXOperatorName: |
3275 | case DeclarationName::CXXConversionFunctionName: |
3276 | InvalidDecl = 6; |
3277 | break; |
3278 | |
3279 | default: |
3280 | InvalidDecl = 0; |
3281 | break; |
3282 | } |
3283 | |
3284 | if (InvalidDecl) { |
3285 | if (ShowDeclName) |
3286 | Diag(Loc, diag::err_invalid_member_in_interface) |
3287 | << (InvalidDecl-1) << Name; |
3288 | else |
3289 | Diag(Loc, diag::err_invalid_member_in_interface) |
3290 | << (InvalidDecl-1) << ""; |
3291 | return nullptr; |
3292 | } |
3293 | } |
3294 | |
3295 | |
3296 | |
3297 | |
3298 | |
3299 | |
3300 | switch (DS.getStorageClassSpec()) { |
3301 | case DeclSpec::SCS_unspecified: |
3302 | case DeclSpec::SCS_typedef: |
3303 | case DeclSpec::SCS_static: |
3304 | break; |
3305 | case DeclSpec::SCS_mutable: |
3306 | if (isFunc) { |
3307 | Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_function); |
3308 | |
3309 | |
3310 | |
3311 | D.getMutableDeclSpec().ClearStorageClassSpecs(); |
3312 | } |
3313 | break; |
3314 | default: |
3315 | Diag(DS.getStorageClassSpecLoc(), |
3316 | diag::err_storageclass_invalid_for_member); |
3317 | D.getMutableDeclSpec().ClearStorageClassSpecs(); |
3318 | break; |
3319 | } |
3320 | |
3321 | bool isInstField = ((DS.getStorageClassSpec() == DeclSpec::SCS_unspecified || |
3322 | DS.getStorageClassSpec() == DeclSpec::SCS_mutable) && |
3323 | !isFunc); |
3324 | |
3325 | if (DS.hasConstexprSpecifier() && isInstField) { |
3326 | SemaDiagnosticBuilder B = |
3327 | Diag(DS.getConstexprSpecLoc(), diag::err_invalid_constexpr_member); |
3328 | SourceLocation ConstexprLoc = DS.getConstexprSpecLoc(); |
3329 | if (InitStyle == ICIS_NoInit) { |
3330 | B << 0 << 0; |
3331 | if (D.getDeclSpec().getTypeQualifiers() & DeclSpec::TQ_const) |
3332 | B << FixItHint::CreateRemoval(ConstexprLoc); |
3333 | else { |
3334 | B << FixItHint::CreateReplacement(ConstexprLoc, "const"); |
3335 | D.getMutableDeclSpec().ClearConstexprSpec(); |
3336 | const char *PrevSpec; |
3337 | unsigned DiagID; |
3338 | bool Failed = D.getMutableDeclSpec().SetTypeQual( |
3339 | DeclSpec::TQ_const, ConstexprLoc, PrevSpec, DiagID, getLangOpts()); |
3340 | (void)Failed; |
3341 | assert(!Failed && "Making a constexpr member const shouldn't fail"); |
3342 | } |
3343 | } else { |
3344 | B << 1; |
3345 | const char *PrevSpec; |
3346 | unsigned DiagID; |
3347 | if (D.getMutableDeclSpec().SetStorageClassSpec( |
3348 | *this, DeclSpec::SCS_static, ConstexprLoc, PrevSpec, DiagID, |
3349 | Context.getPrintingPolicy())) { |
3350 | assert(DS.getStorageClassSpec() == DeclSpec::SCS_mutable && |
3351 | "This is the only DeclSpec that should fail to be applied"); |
3352 | B << 1; |
3353 | } else { |
3354 | B << 0 << FixItHint::CreateInsertion(ConstexprLoc, "static "); |
3355 | isInstField = false; |
3356 | } |
3357 | } |
3358 | } |
3359 | |
3360 | NamedDecl *Member; |
3361 | if (isInstField) { |
3362 | CXXScopeSpec &SS = D.getCXXScopeSpec(); |
3363 | |
3364 | |
3365 | if (!Name.isIdentifier()) { |
3366 | Diag(Loc, diag::err_bad_variable_name) |
3367 | << Name; |
3368 | return nullptr; |
3369 | } |
3370 | |
3371 | IdentifierInfo *II = Name.getAsIdentifierInfo(); |
3372 | |
3373 | |
3374 | |
3375 | if (TemplateParameterLists.size()) { |
3376 | TemplateParameterList* TemplateParams = TemplateParameterLists[0]; |
3377 | if (TemplateParams->size()) { |
3378 | |
3379 | Diag(D.getIdentifierLoc(), diag::err_template_member) |
3380 | << II |
3381 | << SourceRange(TemplateParams->getTemplateLoc(), |
3382 | TemplateParams->getRAngleLoc()); |
3383 | } else { |
3384 | |
3385 | Diag(TemplateParams->getTemplateLoc(), |
3386 | diag::err_template_member_noparams) |
3387 | << II |
3388 | << SourceRange(TemplateParams->getTemplateLoc(), |
3389 | TemplateParams->getRAngleLoc()); |
3390 | } |
3391 | return nullptr; |
3392 | } |
3393 | |
3394 | if (SS.isSet() && !SS.isInvalid()) { |
3395 | |
3396 | |
3397 | |
3398 | |
3399 | |
3400 | |
3401 | if (DeclContext *DC = computeDeclContext(SS, false)) |
3402 | diagnoseQualifiedDeclaration(SS, DC, Name, D.getIdentifierLoc(), |
3403 | D.getName().getKind() == |
3404 | UnqualifiedIdKind::IK_TemplateId); |
3405 | else |
3406 | Diag(D.getIdentifierLoc(), diag::err_member_qualification) |
3407 | << Name << SS.getRange(); |
3408 | |
3409 | SS.clear(); |
3410 | } |
3411 | |
3412 | if (MSPropertyAttr) { |
3413 | Member = HandleMSProperty(S, cast<CXXRecordDecl>(CurContext), Loc, D, |
3414 | BitWidth, InitStyle, AS, *MSPropertyAttr); |
3415 | if (!Member) |
3416 | return nullptr; |
3417 | isInstField = false; |
3418 | } else { |
3419 | Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, |
3420 | BitWidth, InitStyle, AS); |
3421 | if (!Member) |
3422 | return nullptr; |
3423 | } |
3424 | |
3425 | CheckShadowInheritedFields(Loc, Name, cast<CXXRecordDecl>(CurContext)); |
3426 | } else { |
3427 | Member = HandleDeclarator(S, D, TemplateParameterLists); |
3428 | if (!Member) |
3429 | return nullptr; |
3430 | |
3431 | |
3432 | if (BitWidth) { |
3433 | if (Member->isInvalidDecl()) { |
3434 | |
3435 | } else if (isa<VarDecl>(Member) || isa<VarTemplateDecl>(Member)) { |
3436 | |
3437 | |
3438 | Diag(Loc, diag::err_static_not_bitfield) |
3439 | << Name << BitWidth->getSourceRange(); |
3440 | } else if (isa<TypedefDecl>(Member)) { |
3441 | |
3442 | Diag(Loc, diag::err_typedef_not_bitfield) |
3443 | << Name << BitWidth->getSourceRange(); |
3444 | } else { |
3445 | |
3446 | |
3447 | Diag(Loc, diag::err_not_integral_type_bitfield) |
3448 | << Name << cast<ValueDecl>(Member)->getType() |
3449 | << BitWidth->getSourceRange(); |
3450 | } |
3451 | |
3452 | BitWidth = nullptr; |
3453 | Member->setInvalidDecl(); |
3454 | } |
3455 | |
3456 | NamedDecl *NonTemplateMember = Member; |
3457 | if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Member)) |
3458 | NonTemplateMember = FunTmpl->getTemplatedDecl(); |
3459 | else if (VarTemplateDecl *VarTmpl = dyn_cast<VarTemplateDecl>(Member)) |
3460 | NonTemplateMember = VarTmpl->getTemplatedDecl(); |
3461 | |
3462 | Member->setAccess(AS); |
3463 | |
3464 | |
3465 | |
3466 | if (NonTemplateMember != Member) |
3467 | NonTemplateMember->setAccess(AS); |
3468 | |
3469 | |
3470 | |
3471 | |
3472 | if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(NonTemplateMember)) { |
3473 | auto *TD = DG->getDeducedTemplate(); |
3474 | |
3475 | |
3476 | if (AS != TD->getAccess() && |
3477 | TD->getDeclContext()->getRedeclContext()->Equals( |
3478 | DG->getDeclContext()->getRedeclContext())) { |
3479 | Diag(DG->getBeginLoc(), diag::err_deduction_guide_wrong_access); |
3480 | Diag(TD->getBeginLoc(), diag::note_deduction_guide_template_access) |
3481 | << TD->getAccess(); |
3482 | const AccessSpecDecl *LastAccessSpec = nullptr; |
3483 | for (const auto *D : cast<CXXRecordDecl>(CurContext)->decls()) { |
3484 | if (const auto *AccessSpec = dyn_cast<AccessSpecDecl>(D)) |
3485 | LastAccessSpec = AccessSpec; |
3486 | } |
3487 | assert(LastAccessSpec && "differing access with no access specifier"); |
3488 | Diag(LastAccessSpec->getBeginLoc(), diag::note_deduction_guide_access) |
3489 | << AS; |
3490 | } |
3491 | } |
3492 | } |
3493 | |
3494 | if (VS.isOverrideSpecified()) |
3495 | Member->addAttr(OverrideAttr::Create(Context, VS.getOverrideLoc(), |
3496 | AttributeCommonInfo::AS_Keyword)); |
3497 | if (VS.isFinalSpecified()) |
3498 | Member->addAttr(FinalAttr::Create( |
3499 | Context, VS.getFinalLoc(), AttributeCommonInfo::AS_Keyword, |
3500 | static_cast<FinalAttr::Spelling>(VS.isFinalSpelledSealed()))); |
3501 | |
3502 | if (VS.getLastLocation().isValid()) { |
3503 | |
3504 | if (CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Member)) |
3505 | MD->setRangeEnd(VS.getLastLocation()); |
3506 | } |
3507 | |
3508 | CheckOverrideControl(Member); |
3509 | |
3510 | assert((Name || isInstField) && "No identifier for non-field ?"); |
3511 | |
3512 | if (isInstField) { |
3513 | FieldDecl *FD = cast<FieldDecl>(Member); |
3514 | FieldCollector->Add(FD); |
3515 | |
3516 | if (!Diags.isIgnored(diag::warn_unused_private_field, FD->getLocation())) { |
3517 | |
3518 | |
3519 | if (!FD->isImplicit() && FD->getDeclName() && |
3520 | FD->getAccess() == AS_private && |
3521 | !FD->hasAttr<UnusedAttr>() && |
3522 | !FD->getParent()->isDependentContext() && |
3523 | !InitializationHasSideEffects(*FD)) |
3524 | UnusedPrivateFields.insert(FD); |
3525 | } |
3526 | } |
3527 | |
3528 | return Member; |
3529 | } |
3530 | |
3531 | namespace { |
3532 | class UninitializedFieldVisitor |
3533 | : public EvaluatedExprVisitor<UninitializedFieldVisitor> { |
3534 | Sema &S; |
3535 | |
3536 | |
3537 | llvm::SmallPtrSetImpl<ValueDecl*> &Decls; |
3538 | |
3539 | |
3540 | llvm::SmallPtrSetImpl<QualType> &BaseClasses; |
3541 | |
3542 | |
3543 | llvm::SmallVector<ValueDecl*, 4> DeclsToRemove; |
3544 | |
3545 | const CXXConstructorDecl *Constructor; |
3546 | |
3547 | |
3548 | |
3549 | bool InitList; |
3550 | FieldDecl *InitListFieldDecl; |
3551 | llvm::SmallVector<unsigned, 4> InitFieldIndex; |
3552 | |
3553 | public: |
3554 | typedef EvaluatedExprVisitor<UninitializedFieldVisitor> Inherited; |
3555 | UninitializedFieldVisitor(Sema &S, |
3556 | llvm::SmallPtrSetImpl<ValueDecl*> &Decls, |
3557 | llvm::SmallPtrSetImpl<QualType> &BaseClasses) |
3558 | : Inherited(S.Context), S(S), Decls(Decls), BaseClasses(BaseClasses), |
3559 | Constructor(nullptr), InitList(false), InitListFieldDecl(nullptr) {} |
3560 | |
3561 | |
3562 | bool IsInitListMemberExprInitialized(MemberExpr *ME, |
3563 | bool CheckReferenceOnly) { |
3564 | llvm::SmallVector<FieldDecl*, 4> Fields; |
3565 | bool ReferenceField = false; |
3566 | while (ME) { |
3567 | FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()); |
3568 | if (!FD) |
3569 | return false; |
3570 | Fields.push_back(FD); |
3571 | if (FD->getType()->isReferenceType()) |
3572 | ReferenceField = true; |
3573 | ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParenImpCasts()); |
3574 | } |
3575 | |
3576 | |
3577 | |
3578 | if (CheckReferenceOnly && !ReferenceField) |
3579 | return true; |
3580 | |
3581 | llvm::SmallVector<unsigned, 4> UsedFieldIndex; |
3582 | |
3583 | |
3584 | for (auto I = Fields.rbegin() + 1, E = Fields.rend(); I != E; ++I) { |
3585 | UsedFieldIndex.push_back((*I)->getFieldIndex()); |
3586 | } |
3587 | |
3588 | for (auto UsedIter = UsedFieldIndex.begin(), |
3589 | UsedEnd = UsedFieldIndex.end(), |
3590 | OrigIter = InitFieldIndex.begin(), |
3591 | OrigEnd = InitFieldIndex.end(); |
3592 | UsedIter != UsedEnd && OrigIter != OrigEnd; ++UsedIter, ++OrigIter) { |
3593 | if (*UsedIter < *OrigIter) |
3594 | return true; |
3595 | if (*UsedIter > *OrigIter) |
3596 | break; |
3597 | } |
3598 | |
3599 | return false; |
3600 | } |
3601 | |
3602 | void HandleMemberExpr(MemberExpr *ME, bool CheckReferenceOnly, |
3603 | bool AddressOf) { |
3604 | if (isa<EnumConstantDecl>(ME->getMemberDecl())) |
3605 | return; |
3606 | |
3607 | |
3608 | |
3609 | MemberExpr *FieldME = ME; |
3610 | |
3611 | bool AllPODFields = FieldME->getType().isPODType(S.Context); |
3612 | |
3613 | Expr *Base = ME; |
3614 | while (MemberExpr *SubME = |
3615 | dyn_cast<MemberExpr>(Base->IgnoreParenImpCasts())) { |
3616 | |
3617 | if (isa<VarDecl>(SubME->getMemberDecl())) |
3618 | return; |
3619 | |
3620 | if (FieldDecl *FD = dyn_cast<FieldDecl>(SubME->getMemberDecl())) |
3621 | if (!FD->isAnonymousStructOrUnion()) |
3622 | FieldME = SubME; |
3623 | |
3624 | if (!FieldME->getType().isPODType(S.Context)) |
3625 | AllPODFields = false; |
3626 | |
3627 | Base = SubME->getBase(); |
3628 | } |
3629 | |
3630 | if (!isa<CXXThisExpr>(Base->IgnoreParenImpCasts())) { |
3631 | Visit(Base); |
3632 | return; |
3633 | } |
3634 | |
3635 | if (AddressOf && AllPODFields) |
3636 | return; |
3637 | |
3638 | ValueDecl* FoundVD = FieldME->getMemberDecl(); |
3639 | |
3640 | if (ImplicitCastExpr *BaseCast = dyn_cast<ImplicitCastExpr>(Base)) { |
3641 | while (isa<ImplicitCastExpr>(BaseCast->getSubExpr())) { |
3642 | BaseCast = cast<ImplicitCastExpr>(BaseCast->getSubExpr()); |
3643 | } |
3644 | |
3645 | if (BaseCast->getCastKind() == CK_UncheckedDerivedToBase) { |
3646 | QualType T = BaseCast->getType(); |
3647 | if (T->isPointerType() && |
3648 | BaseClasses.count(T->getPointeeType())) { |
3649 | S.Diag(FieldME->getExprLoc(), diag::warn_base_class_is_uninit) |
3650 | << T->getPointeeType() << FoundVD; |
3651 | } |
3652 | } |
3653 | } |
3654 | |
3655 | if (!Decls.count(FoundVD)) |
3656 | return; |
3657 | |
3658 | const bool IsReference = FoundVD->getType()->isReferenceType(); |
3659 | |
3660 | if (InitList && !AddressOf && FoundVD == InitListFieldDecl) { |
3661 | |
3662 | if (IsInitListMemberExprInitialized(ME, CheckReferenceOnly)) { |
3663 | return; |
3664 | } |
3665 | } else { |
3666 | |
3667 | if (CheckReferenceOnly && !IsReference) |
3668 | return; |
3669 | } |
3670 | |
3671 | unsigned diag = IsReference |
3672 | ? diag::warn_reference_field_is_uninit |
3673 | : diag::warn_field_is_uninit; |
3674 | S.Diag(FieldME->getExprLoc(), diag) << FoundVD; |
3675 | if (Constructor) |
3676 | S.Diag(Constructor->getLocation(), |
3677 | diag::note_uninit_in_this_constructor) |
3678 | << (Constructor->isDefaultConstructor() && Constructor->isImplicit()); |
3679 | |
3680 | } |
3681 | |
3682 | void HandleValue(Expr *E, bool AddressOf) { |
3683 | E = E->IgnoreParens(); |
3684 | |
3685 | if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) { |
3686 | HandleMemberExpr(ME, false , |
3687 | AddressOf ); |
3688 | return; |
3689 | } |
3690 | |
3691 | if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { |
3692 | Visit(CO->getCond()); |
3693 | HandleValue(CO->getTrueExpr(), AddressOf); |
3694 | HandleValue(CO->getFalseExpr(), AddressOf); |
3695 | return; |
3696 | } |
3697 | |
3698 | if (BinaryConditionalOperator *BCO = |
3699 | dyn_cast<BinaryConditionalOperator>(E)) { |
3700 | Visit(BCO->getCond()); |
3701 | HandleValue(BCO->getFalseExpr(), AddressOf); |
3702 | return; |
3703 | } |
3704 | |
3705 | if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) { |
3706 | HandleValue(OVE->getSourceExpr(), AddressOf); |
3707 | return; |
3708 | } |
3709 | |
3710 | if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { |
3711 | switch (BO->getOpcode()) { |
3712 | default: |
3713 | break; |
3714 | case(BO_PtrMemD): |
3715 | case(BO_PtrMemI): |
3716 | HandleValue(BO->getLHS(), AddressOf); |
3717 | Visit(BO->getRHS()); |
3718 | return; |
3719 | case(BO_Comma): |
3720 | Visit(BO->getLHS()); |
3721 | HandleValue(BO->getRHS(), AddressOf); |
3722 | return; |
3723 | } |
3724 | } |
3725 | |
3726 | Visit(E); |
3727 | } |
3728 | |
3729 | void CheckInitListExpr(InitListExpr *ILE) { |
3730 | InitFieldIndex.push_back(0); |
3731 | for (auto Child : ILE->children()) { |
3732 | if (InitListExpr *SubList = dyn_cast<InitListExpr>(Child)) { |
3733 | CheckInitListExpr(SubList); |
3734 | } else { |
3735 | Visit(Child); |
3736 | } |
3737 | ++InitFieldIndex.back(); |
3738 | } |
3739 | InitFieldIndex.pop_back(); |
3740 | } |
3741 | |
3742 | void CheckInitializer(Expr *E, const CXXConstructorDecl *FieldConstructor, |
3743 | FieldDecl *Field, const Type *BaseClass) { |
3744 | |
3745 | |
3746 | for (ValueDecl* VD : DeclsToRemove) |
3747 | Decls.erase(VD); |
3748 | DeclsToRemove.clear(); |
3749 | |
3750 | Constructor = FieldConstructor; |
3751 | InitListExpr *ILE = dyn_cast<InitListExpr>(E); |
3752 | |
3753 | if (ILE && Field) { |
3754 | InitList = true; |
3755 | InitListFieldDecl = Field; |
3756 | InitFieldIndex.clear(); |
3757 | CheckInitListExpr(ILE); |
3758 | } else { |
3759 | InitList = false; |
3760 | Visit(E); |
3761 | } |
3762 | |
3763 | if (Field) |
3764 | Decls.erase(Field); |
3765 | if (BaseClass) |
3766 | BaseClasses.erase(BaseClass->getCanonicalTypeInternal()); |
3767 | } |
3768 | |
3769 | void VisitMemberExpr(MemberExpr *ME) { |
3770 | |
3771 | HandleMemberExpr(ME, true , false ); |
3772 | } |
3773 | |
3774 | void VisitImplicitCastExpr(ImplicitCastExpr *E) { |
3775 | if (E->getCastKind() == CK_LValueToRValue) { |
3776 | HandleValue(E->getSubExpr(), false ); |
3777 | return; |
3778 | } |
3779 | |
3780 | Inherited::VisitImplicitCastExpr(E); |
3781 | } |
3782 | |
3783 | void VisitCXXConstructExpr(CXXConstructExpr *E) { |
3784 | if (E->getConstructor()->isCopyConstructor()) { |
3785 | Expr *ArgExpr = E->getArg(0); |
3786 | if (InitListExpr *ILE = dyn_cast<InitListExpr>(ArgExpr)) |
3787 | if (ILE->getNumInits() == 1) |
3788 | ArgExpr = ILE->getInit(0); |
3789 | if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgExpr)) |
3790 | if (ICE->getCastKind() == CK_NoOp) |
3791 | ArgExpr = ICE->getSubExpr(); |
3792 | HandleValue(ArgExpr, false ); |
3793 | return; |
3794 | } |
3795 | Inherited::VisitCXXConstructExpr(E); |
3796 | } |
3797 | |
3798 | void VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { |
3799 | Expr *Callee = E->getCallee(); |
3800 | if (isa<MemberExpr>(Callee)) { |
3801 | HandleValue(Callee, false ); |
3802 | for (auto Arg : E->arguments()) |
3803 | Visit(Arg); |
3804 | return; |
3805 | } |
3806 | |
3807 | Inherited::VisitCXXMemberCallExpr(E); |
3808 | } |
3809 | |
3810 | void VisitCallExpr(CallExpr *E) { |
3811 | |
3812 | if (E->isCallToStdMove()) { |
3813 | HandleValue(E->getArg(0), false); |
3814 | return; |
3815 | } |
3816 | |
3817 | Inherited::VisitCallExpr(E); |
3818 | } |
3819 | |
3820 | void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { |
3821 | Expr *Callee = E->getCallee(); |
3822 | |
3823 | if (isa<UnresolvedLookupExpr>(Callee)) |
3824 | return Inherited::VisitCXXOperatorCallExpr(E); |
3825 | |
3826 | Visit(Callee); |
3827 | for (auto Arg : E->arguments()) |
3828 | HandleValue(Arg->IgnoreParenImpCasts(), false ); |
3829 | } |
3830 | |
3831 | void VisitBinaryOperator(BinaryOperator *E) { |
3832 | |
3833 | |
3834 | if (E->getOpcode() == BO_Assign) |
3835 | if (MemberExpr *ME = dyn_cast<MemberExpr>(E->getLHS())) |
3836 | if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) |
3837 | if (!FD->getType()->isReferenceType()) |
3838 | DeclsToRemove.push_back(FD); |
3839 | |
3840 | if (E->isCompoundAssignmentOp()) { |
3841 | HandleValue(E->getLHS(), false ); |
3842 | Visit(E->getRHS()); |
3843 | return; |
3844 | } |
3845 | |
3846 | Inherited::VisitBinaryOperator(E); |
3847 | } |
3848 | |
3849 | void VisitUnaryOperator(UnaryOperator *E) { |
3850 | if (E->isIncrementDecrementOp()) { |
3851 | HandleValue(E->getSubExpr(), false ); |
3852 | return; |
3853 | } |
3854 | if (E->getOpcode() == UO_AddrOf) { |
3855 | if (MemberExpr *ME = dyn_cast<MemberExpr>(E->getSubExpr())) { |
3856 | HandleValue(ME->getBase(), true ); |
3857 | return; |
3858 | } |
3859 | } |
3860 | |
3861 | Inherited::VisitUnaryOperator(E); |
3862 | } |
3863 | }; |
3864 | |
3865 | |
3866 | |
3867 | |
3868 | |
3869 | |
3870 | |
3871 | static void DiagnoseUninitializedFields( |
3872 | Sema &SemaRef, const CXXConstructorDecl *Constructor) { |
3873 | |
3874 | if (SemaRef.getDiagnostics().isIgnored(diag::warn_field_is_uninit, |
3875 | Constructor->getLocation())) { |
3876 | return; |
3877 | } |
3878 | |
3879 | if (Constructor->isInvalidDecl()) |
3880 | return; |
3881 | |
3882 | const CXXRecordDecl *RD = Constructor->getParent(); |
3883 | |
3884 | if (RD->isDependentContext()) |
3885 | return; |
3886 | |
3887 | |
3888 | llvm::SmallPtrSet<ValueDecl*, 4> UninitializedFields; |
3889 | |
3890 | |
3891 | for (auto *I : RD->decls()) { |
3892 | if (auto *FD = dyn_cast<FieldDecl>(I)) { |
3893 | UninitializedFields.insert(FD); |
3894 | } else if (auto *IFD = dyn_cast<IndirectFieldDecl>(I)) { |
3895 | UninitializedFields.insert(IFD->getAnonField()); |
3896 | } |
3897 | } |
3898 | |
3899 | llvm::SmallPtrSet<QualType, 4> UninitializedBaseClasses; |
3900 | for (auto I : RD->bases()) |
3901 | UninitializedBaseClasses.insert(I.getType().getCanonicalType()); |
3902 | |
3903 | if (UninitializedFields.empty() && UninitializedBaseClasses.empty()) |
3904 | return; |
3905 | |
3906 | UninitializedFieldVisitor UninitializedChecker(SemaRef, |
3907 | UninitializedFields, |
3908 | UninitializedBaseClasses); |
3909 | |
3910 | for (const auto *FieldInit : Constructor->inits()) { |
3911 | if (UninitializedFields.empty() && UninitializedBaseClasses.empty()) |
3912 | break; |
3913 | |
3914 | Expr *InitExpr = FieldInit->getInit(); |
3915 | if (!InitExpr) |
3916 | continue; |
3917 | |
3918 | if (CXXDefaultInitExpr *Default = |
3919 | dyn_cast<CXXDefaultInitExpr>(InitExpr)) { |
3920 | InitExpr = Default->getExpr(); |
3921 | if (!InitExpr) |
3922 | continue; |
3923 | |
3924 | UninitializedChecker.CheckInitializer(InitExpr, Constructor, |
3925 | FieldInit->getAnyMember(), |
3926 | FieldInit->getBaseClass()); |
3927 | } else { |
3928 | UninitializedChecker.CheckInitializer(InitExpr, nullptr, |
3929 | FieldInit->getAnyMember(), |
3930 | FieldInit->getBaseClass()); |
3931 | } |
3932 | } |
3933 | } |
3934 | } |
3935 | |
3936 | |
3937 | |
3938 | |
3939 | void Sema::ActOnStartCXXInClassMemberInitializer() { |
3940 | |
3941 | |
3942 | PushFunctionScope(); |
3943 | } |
3944 | |
3945 | void Sema::ActOnStartTrailingRequiresClause(Scope *S, Declarator &D) { |
3946 | if (!D.isFunctionDeclarator()) |
3947 | return; |
3948 | auto &FTI = D.getFunctionTypeInfo(); |
3949 | if (!FTI.Params) |
3950 | return; |
3951 | for (auto &Param : ArrayRef<DeclaratorChunk::ParamInfo>(FTI.Params, |
3952 | FTI.NumParams)) { |
3953 | auto *ParamDecl = cast<NamedDecl>(Param.Param); |
3954 | if (ParamDecl->getDeclName()) |
3955 | PushOnScopeChains(ParamDecl, S, false); |
3956 | } |
3957 | } |
3958 | |
3959 | ExprResult Sema::ActOnFinishTrailingRequiresClause(ExprResult ConstraintExpr) { |
3960 | return ActOnRequiresClause(ConstraintExpr); |
3961 | } |
3962 | |
3963 | ExprResult Sema::ActOnRequiresClause(ExprResult ConstraintExpr) { |
3964 | if (ConstraintExpr.isInvalid()) |
3965 | return ExprError(); |
3966 | |
3967 | ConstraintExpr = CorrectDelayedTyposInExpr(ConstraintExpr); |
3968 | if (ConstraintExpr.isInvalid()) |
3969 | return ExprError(); |
3970 | |
3971 | if (DiagnoseUnexpandedParameterPack(ConstraintExpr.get(), |
3972 | UPPC_RequiresClause)) |
3973 | return ExprError(); |
3974 | |
3975 | return ConstraintExpr; |
3976 | } |
3977 | |
3978 | |
3979 | |
3980 | |
3981 | void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D, |
3982 | SourceLocation InitLoc, |
3983 | Expr *InitExpr) { |
3984 | |
3985 | PopFunctionScopeInfo(nullptr, D); |
3986 | |
3987 | FieldDecl *FD = dyn_cast<FieldDecl>(D); |
3988 | assert((isa<MSPropertyDecl>(D) || FD->getInClassInitStyle() != ICIS_NoInit) && |
3989 | "must set init style when field is created"); |
3990 | |
3991 | if (!InitExpr) { |
3992 | D->setInvalidDecl(); |
3993 | if (FD) |
3994 | FD->removeInClassInitializer(); |
3995 | return; |
3996 | } |
3997 | |
3998 | if (DiagnoseUnexpandedParameterPack(InitExpr, UPPC_Initializer)) { |
3999 | FD->setInvalidDecl(); |
4000 | FD->removeInClassInitializer(); |
4001 | return; |
4002 | } |
4003 | |
4004 | ExprResult Init = InitExpr; |
4005 | if (!FD->getType()->isDependentType() && !InitExpr->isTypeDependent()) { |
4006 | InitializedEntity Entity = |
4007 | InitializedEntity::InitializeMemberFromDefaultMemberInitializer(FD); |
4008 | InitializationKind Kind = |
4009 | FD->getInClassInitStyle() == ICIS_ListInit |
4010 | ? InitializationKind::CreateDirectList(InitExpr->getBeginLoc(), |
4011 | InitExpr->getBeginLoc(), |
4012 | InitExpr->getEndLoc()) |
4013 | : InitializationKind::CreateCopy(InitExpr->getBeginLoc(), InitLoc); |
4014 | InitializationSequence Seq(*this, Entity, Kind, InitExpr); |
4015 | Init = Seq.Perform(*this, Entity, Kind, InitExpr); |
4016 | if (Init.isInvalid()) { |
4017 | FD->setInvalidDecl(); |
4018 | return; |
4019 | } |
4020 | } |
4021 | |
4022 | |
4023 | |
4024 | |
4025 | Init = ActOnFinishFullExpr(Init.get(), InitLoc, false); |
4026 | if (Init.isInvalid()) { |
4027 | FD->setInvalidDecl(); |
4028 | return; |
4029 | } |
4030 | |
4031 | InitExpr = Init.get(); |
4032 | |
4033 | FD->setInClassInitializer(InitExpr); |
4034 | } |
4035 | |
4036 | |
4037 | |
4038 | |
4039 | static bool FindBaseInitializer(Sema &SemaRef, |
4040 | CXXRecordDecl *ClassDecl, |
4041 | QualType BaseType, |
4042 | const CXXBaseSpecifier *&DirectBaseSpec, |
4043 | const CXXBaseSpecifier *&VirtualBaseSpec) { |
4044 | |
4045 | DirectBaseSpec = nullptr; |
4046 | for (const auto &Base : ClassDecl->bases()) { |
4047 | if (SemaRef.Context.hasSameUnqualifiedType(BaseType, Base.getType())) { |
4048 | |
4049 | |
4050 | DirectBaseSpec = &Base; |
4051 | break; |
4052 | } |
4053 | } |
4054 | |
4055 | |
4056 | |
4057 | |
4058 | VirtualBaseSpec = nullptr; |
4059 | if (!DirectBaseSpec || !DirectBaseSpec->isVirtual()) { |
4060 | |
4061 | |
4062 | CXXBasePaths Paths(true, true, |
4063 | false); |
4064 | if (SemaRef.IsDerivedFrom(ClassDecl->getLocation(), |
4065 | SemaRef.Context.getTypeDeclType(ClassDecl), |
4066 | BaseType, Paths)) { |
4067 | for (CXXBasePaths::paths_iterator Path = Paths.begin(); |
4068 | Path != Paths.end(); ++Path) { |
4069 | if (Path->back().Base->isVirtual()) { |
4070 | VirtualBaseSpec = Path->back().Base; |
4071 | break; |
4072 | } |
4073 | } |
4074 | } |
4075 | } |
4076 | |
4077 | return DirectBaseSpec || VirtualBaseSpec; |
4078 | } |
4079 | |
4080 | |
4081 | MemInitResult |
4082 | Sema::ActOnMemInitializer(Decl *ConstructorD, |
4083 | Scope *S, |
4084 | CXXScopeSpec &SS, |
4085 | IdentifierInfo *MemberOrBase, |
4086 | ParsedType TemplateTypeTy, |
4087 | const DeclSpec &DS, |
4088 | SourceLocation IdLoc, |
4089 | Expr *InitList, |
4090 | SourceLocation EllipsisLoc) { |
4091 | return BuildMemInitializer(ConstructorD, S, SS, MemberOrBase, TemplateTypeTy, |
4092 | DS, IdLoc, InitList, |
4093 | EllipsisLoc); |
4094 | } |
4095 | |
4096 | |
4097 | MemInitResult |
4098 | Sema::ActOnMemInitializer(Decl *ConstructorD, |
4099 | Scope *S, |
4100 | CXXScopeSpec &SS, |
4101 | IdentifierInfo *MemberOrBase, |
4102 | ParsedType TemplateTypeTy, |
4103 | const DeclSpec &DS, |
4104 | SourceLocation IdLoc, |
4105 | SourceLocation LParenLoc, |
4106 | ArrayRef<Expr *> Args, |
4107 | SourceLocation RParenLoc, |
4108 | SourceLocation EllipsisLoc) { |
4109 | Expr *List = ParenListExpr::Create(Context, LParenLoc, Args, RParenLoc); |
4110 | return BuildMemInitializer(ConstructorD, S, SS, MemberOrBase, TemplateTypeTy, |
4111 | DS, IdLoc, List, EllipsisLoc); |
4112 | } |
4113 | |
4114 | namespace { |
4115 | |
4116 | |
4117 | |
4118 | class MemInitializerValidatorCCC final : public CorrectionCandidateCallback { |
4119 | public: |
4120 | explicit MemInitializerValidatorCCC(CXXRecordDecl *ClassDecl) |
4121 | : ClassDecl(ClassDecl) {} |
4122 | |
4123 | bool ValidateCandidate(const TypoCorrection &candidate) override { |
4124 | if (NamedDecl *ND = candidate.getCorrectionDecl()) { |
4125 | if (FieldDecl *Member = dyn_cast<FieldDecl>(ND)) |
4126 | return Member->getDeclContext()->getRedeclContext()->Equals(ClassDecl); |
4127 | return isa<TypeDecl>(ND); |
4128 | } |
4129 | return false; |
4130 | } |
4131 | |
4132 | std::unique_ptr<CorrectionCandidateCallback> clone() override { |
4133 | return std::make_unique<MemInitializerValidatorCCC>(*this); |
4134 | } |
4135 | |
4136 | private: |
4137 | CXXRecordDecl *ClassDecl; |
4138 | }; |
4139 | |
4140 | } |
4141 | |
4142 | ValueDecl *Sema::tryLookupCtorInitMemberDecl(CXXRecordDecl *ClassDecl, |
4143 | CXXScopeSpec &SS, |
4144 | ParsedType TemplateTypeTy, |
4145 | IdentifierInfo *MemberOrBase) { |
4146 | if (SS.getScopeRep() || TemplateTypeTy) |
4147 | return nullptr; |
4148 | for (auto *D : ClassDecl->lookup(MemberOrBase)) |
4149 | if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) |
4150 | return cast<ValueDecl>(D); |
4151 | return nullptr; |
4152 | } |
4153 | |
4154 | |
4155 | MemInitResult |
4156 | Sema::BuildMemInitializer(Decl *ConstructorD, |
4157 | Scope *S, |
4158 | CXXScopeSpec &SS, |
4159 | IdentifierInfo *MemberOrBase, |
4160 | ParsedType TemplateTypeTy, |
4161 | const DeclSpec &DS, |
4162 | SourceLocation IdLoc, |
4163 | Expr *Init, |
4164 | SourceLocation EllipsisLoc) { |
4165 | ExprResult Res = CorrectDelayedTyposInExpr(Init); |
4166 | if (!Res.isUsable()) |
4167 | return true; |
4168 | Init = Res.get(); |
4169 | |
4170 | if (!ConstructorD) |
4171 | return true; |
4172 | |
4173 | AdjustDeclIfTemplate(ConstructorD); |
4174 | |
4175 | CXXConstructorDecl *Constructor |
4176 | = dyn_cast<CXXConstructorDecl>(ConstructorD); |
4177 | if (!Constructor) { |
4178 | |
4179 | |
4180 | |
4181 | |
4182 | return true; |
4183 | } |
4184 | |
4185 | CXXRecordDecl *ClassDecl = Constructor->getParent(); |
4186 | |
4187 | |
4188 | |
4189 | |
4190 | |
4191 | |
4192 | |
4193 | |
4194 | |
4195 | |
4196 | |
4197 | |
4198 | |
4199 | if (ValueDecl *Member = tryLookupCtorInitMemberDecl( |
4200 | ClassDecl, SS, TemplateTypeTy, MemberOrBase)) { |
4201 | if (EllipsisLoc.isValid()) |
4202 | Diag(EllipsisLoc, diag::err_pack_expansion_member_init) |
4203 | << MemberOrBase |
4204 | << SourceRange(IdLoc, Init->getSourceRange().getEnd()); |
4205 | |
4206 | return BuildMemberInitializer(Member, Init, IdLoc); |
4207 | } |
4208 | |
4209 | QualType BaseType; |
4210 | TypeSourceInfo *TInfo = nullptr; |
4211 | |
4212 | if (TemplateTypeTy) { |
4213 | BaseType = GetTypeFromParser(TemplateTypeTy, &TInfo); |
4214 | if (BaseType.isNull()) |
4215 | return true; |
4216 | } else if (DS.getTypeSpecType() == TST_decltype) { |
4217 | BaseType = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc()); |
4218 | } else if (DS.getTypeSpecType() == TST_decltype_auto) { |
4219 | Diag(DS.getTypeSpecTypeLoc(), diag::err_decltype_auto_invalid); |
4220 | return true; |
4221 | } else { |
4222 | LookupResult R(*this, MemberOrBase, IdLoc, LookupOrdinaryName); |
4223 | LookupParsedName(R, S, &SS); |
4224 | |
4225 | TypeDecl *TyD = R.getAsSingle<TypeDecl>(); |
4226 | if (!TyD) { |
4227 | if (R.isAmbiguous()) return true; |
4228 | |
4229 | |
4230 | R.suppressDiagnostics(); |
4231 | |
4232 | if (SS.isSet() && isDependentScopeSpecifier(SS)) { |
4233 | bool NotUnknownSpecialization = false; |
4234 | DeclContext *DC = computeDeclContext(SS, false); |
4235 | if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(DC)) |
4236 | NotUnknownSpecialization = !Record->hasAnyDependentBases(); |
4237 | |
4238 | if (!NotUnknownSpecialization) { |
4239 | |
4240 | |
4241 | BaseType = CheckTypenameType(ETK_None, SourceLocation(), |
4242 | SS.getWithLocInContext(Context), |
4243 | *MemberOrBase, IdLoc); |
4244 | if (BaseType.isNull()) |
4245 | return true; |
4246 | |
4247 | TInfo = Context.CreateTypeSourceInfo(BaseType); |
4248 | DependentNameTypeLoc TL = |
4249 | TInfo->getTypeLoc().castAs<DependentNameTypeLoc>(); |
4250 | if (!TL.isNull()) { |
4251 | TL.setNameLoc(IdLoc); |
4252 | TL.setElaboratedKeywordLoc(SourceLocation()); |
4253 | TL.setQualifierLoc(SS.getWithLocInContext(Context)); |
4254 | } |
4255 | |
4256 | R.clear(); |
4257 | R.setLookupName(MemberOrBase); |
4258 | } |
4259 | } |
4260 | |
4261 | |
4262 | TypoCorrection Corr; |
4263 | MemInitializerValidatorCCC CCC(ClassDecl); |
4264 | if (R.empty() && BaseType.isNull() && |
4265 | (Corr = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, |
4266 | CCC, CTK_ErrorRecovery, ClassDecl))) { |
4267 | if (FieldDecl *Member = Corr.getCorrectionDeclAs<FieldDecl>()) { |
4268 | |
4269 | |
4270 | |
4271 | diagnoseTypo(Corr, |
4272 | PDiag(diag::err_mem_init_not_member_or_class_suggest) |
4273 | << MemberOrBase << true); |
4274 | return BuildMemberInitializer(Member, Init, IdLoc); |
4275 | } else if (TypeDecl *Type = Corr.getCorrectionDeclAs<TypeDecl>()) { |
4276 | const CXXBaseSpecifier *DirectBaseSpec; |
4277 | const CXXBaseSpecifier *VirtualBaseSpec; |
4278 | if (FindBaseInitializer(*this, ClassDecl, |
4279 | Context.getTypeDeclType(Type), |
4280 | DirectBaseSpec, VirtualBaseSpec)) { |
4281 | |
4282 | |
4283 | |
4284 | diagnoseTypo(Corr, |
4285 | PDiag(diag::err_mem_init_not_member_or_class_suggest) |
4286 | << MemberOrBase << false, |
4287 | PDiag() ); |
4288 | |
4289 | const CXXBaseSpecifier *BaseSpec = DirectBaseSpec ? DirectBaseSpec |
4290 | : VirtualBaseSpec; |
4291 | Diag(BaseSpec->getBeginLoc(), diag::note_base_class_specified_here) |
4292 | << BaseSpec->getType() << BaseSpec->getSourceRange(); |
4293 | |
4294 | TyD = Type; |
4295 | } |
4296 | } |
4297 | } |
4298 | |
4299 | if (!TyD && BaseType.isNull()) { |
4300 | Diag(IdLoc, diag::err_mem_init_not_member_or_class) |
4301 | << MemberOrBase << SourceRange(IdLoc,Init->getSourceRange().getEnd()); |
4302 | return true; |
4303 | } |
4304 | } |
4305 | |
4306 | if (BaseType.isNull()) { |
4307 | BaseType = Context.getTypeDeclType(TyD); |
4308 | MarkAnyDeclReferenced(TyD->getLocation(), TyD, false); |
4309 | if (SS.isSet()) { |
4310 | BaseType = Context.getElaboratedType(ETK_None, SS.getScopeRep(), |
4311 | BaseType); |
4312 | TInfo = Context.CreateTypeSourceInfo(BaseType); |
4313 | ElaboratedTypeLoc TL = TInfo->getTypeLoc().castAs<ElaboratedTypeLoc>(); |
4314 | TL.getNamedTypeLoc().castAs<TypeSpecTypeLoc>().setNameLoc(IdLoc); |
4315 | TL.setElaboratedKeywordLoc(SourceLocation()); |
4316 | TL.setQualifierLoc(SS.getWithLocInContext(Context)); |
4317 | } |
4318 | } |
4319 | } |
4320 | |
4321 | if (!TInfo) |
4322 | TInfo = Context.getTrivialTypeSourceInfo(BaseType, IdLoc); |
4323 | |
4324 | return BuildBaseInitializer(BaseType, TInfo, Init, ClassDecl, EllipsisLoc); |
4325 | } |
4326 | |
4327 | MemInitResult |
4328 | Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init, |
4329 | SourceLocation IdLoc) { |
4330 | FieldDecl *DirectMember = dyn_cast<FieldDecl>(Member); |
4331 | IndirectFieldDecl *IndirectMember = dyn_cast<IndirectFieldDecl>(Member); |
4332 | assert((DirectMember || IndirectMember) && |
4333 | "Member must be a FieldDecl or IndirectFieldDecl"); |
4334 | |
4335 | if (DiagnoseUnexpandedParameterPack(Init, UPPC_Initializer)) |
4336 | return true; |
4337 | |
4338 | if (Member->isInvalidDecl()) |
4339 | return true; |
4340 | |
4341 | MultiExprArg Args; |
4342 | if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { |
4343 | Args = MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs()); |
4344 | } else if (InitListExpr *InitList = dyn_cast<InitListExpr>(Init)) { |
4345 | Args = MultiExprArg(InitList->getInits(), InitList->getNumInits()); |
4346 | } else { |
4347 | |
4348 | Args = Init; |
4349 | } |
4350 | |
4351 | SourceRange InitRange = Init->getSourceRange(); |
4352 | |
4353 | if (Member->getType()->isDependentType() || Init->isTypeDependent()) { |
4354 | |
4355 | |
4356 | DiscardCleanupsInEvaluationContext(); |
4357 | } else { |
4358 | bool InitList = false; |
4359 | if (isa<InitListExpr>(Init)) { |
4360 | InitList = true; |
4361 | Args = Init; |
4362 | } |
4363 | |
4364 | |
4365 | InitializedEntity MemberEntity = |
4366 | DirectMember ? InitializedEntity::InitializeMember(DirectMember, nullptr) |
4367 | : InitializedEntity::InitializeMember(IndirectMember, |
4368 | nullptr); |
4369 | InitializationKind Kind = |
4370 | InitList ? InitializationKind::CreateDirectList( |
4371 | IdLoc, Init->getBeginLoc(), Init->getEndLoc()) |
4372 | : InitializationKind::CreateDirect(IdLoc, InitRange.getBegin(), |
4373 | InitRange.getEnd()); |
4374 | |
4375 | InitializationSequence InitSeq(*this, MemberEntity, Kind, Args); |
4376 | ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind, Args, |
4377 | nullptr); |
4378 | if (MemberInit.isInvalid()) |
4379 | return true; |
4380 | |
4381 | |
4382 | |
4383 | |
4384 | MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin(), |
4385 | false); |
4386 | if (MemberInit.isInvalid()) |
4387 | return true; |
4388 | |
4389 | Init = MemberInit.get(); |
4390 | } |
4391 | |
4392 | if (DirectMember) { |
4393 | return new (Context) CXXCtorInitializer(Context, DirectMember, IdLoc, |
4394 | InitRange.getBegin(), Init, |
4395 | InitRange.getEnd()); |
4396 | } else { |
4397 | return new (Context) CXXCtorInitializer(Context, IndirectMember, IdLoc, |
4398 | InitRange.getBegin(), Init, |
4399 | InitRange.getEnd()); |
4400 | } |
4401 | } |
4402 | |
4403 | MemInitResult |
4404 | Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init, |
4405 | CXXRecordDecl *ClassDecl) { |
4406 | SourceLocation NameLoc = TInfo->getTypeLoc().getLocalSourceRange().getBegin(); |
4407 | if (!LangOpts.CPlusPlus11) |
4408 | return Diag(NameLoc, diag::err_delegating_ctor) |
4409 | << TInfo->getTypeLoc().getLocalSourceRange(); |
4410 | Diag(NameLoc, diag::warn_cxx98_compat_delegating_ctor); |
4411 | |
4412 | bool InitList = true; |
4413 | MultiExprArg Args = Init; |
4414 | if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { |
4415 | InitList = false; |
4416 | Args = MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs()); |
4417 | } |
4418 | |
4419 | SourceRange InitRange = Init->getSourceRange(); |
4420 | |
4421 | InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation( |
4422 | QualType(ClassDecl->getTypeForDecl(), 0)); |
4423 | InitializationKind Kind = |
4424 | InitList ? InitializationKind::CreateDirectList( |
4425 | NameLoc, Init->getBeginLoc(), Init->getEndLoc()) |
4426 | : InitializationKind::CreateDirect(NameLoc, InitRange.getBegin(), |
4427 | InitRange.getEnd()); |
4428 | InitializationSequence InitSeq(*this, DelegationEntity, Kind, Args); |
4429 | ExprResult DelegationInit = InitSeq.Perform(*this, DelegationEntity, Kind, |
4430 | Args, nullptr); |
4431 | if (DelegationInit.isInvalid()) |
4432 | return true; |
4433 | |
4434 | assert(cast<CXXConstructExpr>(DelegationInit.get())->getConstructor() && |
4435 | "Delegating constructor with no target?"); |
4436 | |
4437 | |
4438 | |
4439 | |
4440 | DelegationInit = ActOnFinishFullExpr( |
4441 | DelegationInit.get(), InitRange.getBegin(), false); |
4442 | if (DelegationInit.isInvalid()) |
4443 | return true; |
4444 | |
4445 | |
4446 | |
4447 | |
4448 | |
4449 | |
4450 | |
4451 | |
4452 | if (CurContext->isDependentContext()) |
4453 | DelegationInit = Init; |
4454 | |
4455 | return new (Context) CXXCtorInitializer(Context, TInfo, InitRange.getBegin(), |
4456 | DelegationInit.getAs<Expr>(), |
4457 | InitRange.getEnd()); |
4458 | } |
4459 | |
4460 | MemInitResult |
4461 | Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, |
4462 | Expr *Init, CXXRecordDecl *ClassDecl, |
4463 | SourceLocation EllipsisLoc) { |
4464 | SourceLocation BaseLoc |
4465 | = BaseTInfo->getTypeLoc().getLocalSourceRange().getBegin(); |
4466 | |
4467 | if (!BaseType->isDependentType() && !BaseType->isRecordType()) |
4468 | return Diag(BaseLoc, diag::err_base_init_does_not_name_class) |
4469 | << BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange(); |
4470 | |
4471 | |
4472 | |
4473 | |
4474 | |
4475 | |
4476 | |
4477 | bool Dependent = BaseType->isDependentType() || Init->isTypeDependent(); |
4478 | |
4479 | SourceRange InitRange = Init->getSourceRange(); |
4480 | if (EllipsisLoc.isValid()) { |
4481 | |
4482 | if (!BaseType->containsUnexpandedParameterPack()) { |
4483 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) |
4484 | << SourceRange(BaseLoc, InitRange.getEnd()); |
4485 | |
4486 | EllipsisLoc = SourceLocation(); |
4487 | } |
4488 | } else { |
4489 | |
4490 | if (DiagnoseUnexpandedParameterPack(BaseLoc, BaseTInfo, UPPC_Initializer)) |
4491 | return true; |
4492 | |
4493 | if (DiagnoseUnexpandedParameterPack(Init, UPPC_Initializer)) |
4494 | return true; |
4495 | } |
4496 | |
4497 | |
4498 | const CXXBaseSpecifier *DirectBaseSpec = nullptr; |
4499 | const CXXBaseSpecifier *VirtualBaseSpec = nullptr; |
4500 | if (!Dependent) { |
4501 | if (Context.hasSameUnqualifiedType(QualType(ClassDecl->getTypeForDecl(),0), |
4502 | BaseType)) |
4503 | return BuildDelegatingInitializer(BaseTInfo, Init, ClassDecl); |
4504 | |
4505 | FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec, |
4506 | VirtualBaseSpec); |
4507 | |
4508 | |
4509 | |
4510 | |
4511 | |
4512 | if (!DirectBaseSpec && !VirtualBaseSpec) { |
4513 | |
4514 | |
4515 | |
4516 | |
4517 | |
4518 | if (ClassDecl->hasAnyDependentBases()) |
4519 | Dependent = true; |
4520 | else |
4521 | return Diag(BaseLoc, diag::err_not_direct_base_or_virtual) |
4522 | << BaseType << Context.getTypeDeclType(ClassDecl) |
4523 | << BaseTInfo->getTypeLoc().getLocalSourceRange(); |
4524 | } |
4525 | } |
4526 | |
4527 | if (Dependent) { |
4528 | DiscardCleanupsInEvaluationContext(); |
4529 | |
4530 | return new (Context) CXXCtorInitializer(Context, BaseTInfo, |
4531 | false, |
4532 | InitRange.getBegin(), Init, |
4533 | InitRange.getEnd(), EllipsisLoc); |
4534 | } |
4535 | |
4536 | |
4537 | |
4538 | |
4539 | |
4540 | if (DirectBaseSpec && VirtualBaseSpec) |
4541 | return Diag(BaseLoc, diag::err_base_init_direct_and_virtual) |
4542 | << BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange(); |
4543 | |
4544 | const CXXBaseSpecifier *BaseSpec = DirectBaseSpec; |
4545 | if (!BaseSpec) |
4546 | BaseSpec = VirtualBaseSpec; |
4547 | |
4548 | |
4549 | bool InitList = true; |
4550 | MultiExprArg Args = Init; |
4551 | if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { |
4552 | InitList = false; |
4553 | Args = MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs()); |
4554 | } |
4555 | |
4556 | InitializedEntity BaseEntity = |
4557 | InitializedEntity::InitializeBase(Context, BaseSpec, VirtualBaseSpec); |
4558 | InitializationKind Kind = |
4559 | InitList ? InitializationKind::CreateDirectList(BaseLoc) |
4560 | : InitializationKind::CreateDirect(BaseLoc, InitRange.getBegin(), |
4561 | InitRange.getEnd()); |
4562 | InitializationSequence InitSeq(*this, BaseEntity, Kind, Args); |
4563 | ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind, Args, nullptr); |
4564 | if (BaseInit.isInvalid()) |
4565 | return true; |
4566 | |
4567 | |
4568 | |
4569 | |
4570 | BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin(), |
4571 | false); |
4572 | if (BaseInit.isInvalid()) |
4573 | return true; |
4574 | |
4575 | |
4576 | |
4577 | |
4578 | |
4579 | |
4580 | |
4581 | |
4582 | if (CurContext->isDependentContext()) |
4583 | BaseInit = Init; |
4584 | |
4585 | return new (Context) CXXCtorInitializer(Context, BaseTInfo, |
4586 | BaseSpec->isVirtual(), |
4587 | InitRange.getBegin(), |
4588 | BaseInit.getAs<Expr>(), |
4589 | InitRange.getEnd(), EllipsisLoc); |
4590 | } |
4591 | |
4592 | |
4593 | static Expr *CastForMoving(Sema &SemaRef, Expr *E, QualType T = QualType()) { |
4594 | if (T.isNull()) T = E->getType(); |
4595 | QualType TargetType = SemaRef.BuildReferenceType( |
4596 | T, false, SourceLocation(), DeclarationName()); |
4597 | SourceLocation ExprLoc = E->getBeginLoc(); |
4598 | TypeSourceInfo *TargetLoc = SemaRef.Context.getTrivialTypeSourceInfo( |
4599 | TargetType, ExprLoc); |
4600 | |
4601 | return SemaRef.BuildCXXNamedCast(ExprLoc, tok::kw_static_cast, TargetLoc, E, |
4602 | SourceRange(ExprLoc, ExprLoc), |
4603 | E->getSourceRange()).get(); |
4604 | } |
4605 | |
4606 | |
4607 | |
4608 | enum ImplicitInitializerKind { |
4609 | IIK_Default, |
4610 | IIK_Copy, |
4611 | IIK_Move, |
4612 | IIK_Inherit |
4613 | }; |
4614 | |
4615 | static bool |
4616 | BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, |
4617 | ImplicitInitializerKind ImplicitInitKind, |
4618 | CXXBaseSpecifier *BaseSpec, |
4619 | bool IsInheritedVirtualBase, |
4620 | CXXCtorInitializer *&CXXBaseInit) { |
4621 | InitializedEntity InitEntity |
4622 | = InitializedEntity::InitializeBase(SemaRef.Context, BaseSpec, |
4623 | IsInheritedVirtualBase); |
4624 | |
4625 | ExprResult BaseInit; |
4626 | |
4627 | switch (ImplicitInitKind) { |
4628 | case IIK_Inherit: |
4629 | case IIK_Default: { |
4630 | InitializationKind InitKind |
4631 | = InitializationKind::CreateDefault(Constructor->getLocation()); |
4632 | InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, None); |
4633 | BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, None); |
4634 | break; |
4635 | } |
4636 | |
4637 | case IIK_Move: |
4638 | case IIK_Copy: { |
4639 | bool Moving = ImplicitInitKind == IIK_Move; |
4640 | ParmVarDecl *Param = Constructor->getParamDecl(0); |
4641 | QualType ParamType = Param->getType().getNonReferenceType(); |
4642 | |
4643 | Expr *CopyCtorArg = |
4644 | DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), |
4645 | SourceLocation(), Param, false, |
4646 | Constructor->getLocation(), ParamType, |
4647 | VK_LValue, nullptr); |
4648 | |
4649 | SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(CopyCtorArg)); |
4650 | |
4651 | |
4652 | QualType ArgTy = |
4653 | SemaRef.Context.getQualifiedType(BaseSpec->getType().getUnqualifiedType(), |
4654 | ParamType.getQualifiers()); |
4655 | |
4656 | if (Moving) { |
4657 | CopyCtorArg = CastForMoving(SemaRef, CopyCtorArg); |
4658 | } |
4659 | |
4660 | CXXCastPath BasePath; |
4661 | BasePath.push_back(BaseSpec); |
4662 | CopyCtorArg = SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy, |
4663 | CK_UncheckedDerivedToBase, |
4664 | Moving ? VK_XValue : VK_LValue, |
4665 | &BasePath).get(); |
4666 | |
4667 | InitializationKind InitKind |
4668 | = InitializationKind::CreateDirect(Constructor->getLocation(), |
4669 | SourceLocation(), SourceLocation()); |
4670 | InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, CopyCtorArg); |
4671 | BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, CopyCtorArg); |
4672 | break; |
4673 | } |
4674 | } |
4675 | |
4676 | BaseInit = SemaRef.MaybeCreateExprWithCleanups(BaseInit); |
4677 | if (BaseInit.isInvalid()) |
4678 | return true; |
4679 | |
4680 | CXXBaseInit = |
4681 | new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, |
4682 | SemaRef.Context.getTrivialTypeSourceInfo(BaseSpec->getType(), |
4683 | SourceLocation()), |
4684 | BaseSpec->isVirtual(), |
4685 | SourceLocation(), |
4686 | BaseInit.getAs<Expr>(), |
4687 | SourceLocation(), |
4688 | SourceLocation()); |
4689 | |
4690 | return false; |
4691 | } |
4692 | |
4693 | static bool RefersToRValueRef(Expr *MemRef) { |
4694 | ValueDecl *Referenced = cast<MemberExpr>(MemRef)->getMemberDecl(); |
4695 | return Referenced->getType()->isRValueReferenceType(); |
4696 | } |
4697 | |
4698 | static bool |
4699 | BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, |
4700 | ImplicitInitializerKind ImplicitInitKind, |
4701 | FieldDecl *Field, IndirectFieldDecl *Indirect, |
4702 | CXXCtorInitializer *&CXXMemberInit) { |
4703 | if (Field->isInvalidDecl()) |
4704 | return true; |
4705 | |
4706 | SourceLocation Loc = Constructor->getLocation(); |
4707 | |
4708 | if (ImplicitInitKind == IIK_Copy || ImplicitInitKind == IIK_Move) { |
4709 | bool Moving = ImplicitInitKind == IIK_Move; |
4710 | ParmVarDecl *Param = Constructor->getParamDecl(0); |
4711 | QualType ParamType = Param->getType().getNonReferenceType(); |
4712 | |
4713 | |
4714 | if (Field->isZeroLengthBitField(SemaRef.Context)) |
4715 | return false; |
4716 | |
4717 | Expr *MemberExprBase = |
4718 | DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), |
4719 | SourceLocation(), Param, false, |
4720 | Loc, ParamType, VK_LValue, nullptr); |
4721 | |
4722 | SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(MemberExprBase)); |
4723 | |
4724 | if (Moving) { |
4725 | MemberExprBase = CastForMoving(SemaRef, MemberExprBase); |
4726 | } |
4727 | |
4728 | |
4729 | CXXScopeSpec SS; |
4730 | LookupResult MemberLookup(SemaRef, Field->getDeclName(), Loc, |
4731 | Sema::LookupMemberName); |
4732 | MemberLookup.addDecl(Indirect ? cast<ValueDecl>(Indirect) |
4733 | : cast<ValueDecl>(Field), AS_public); |
4734 | MemberLookup.resolveKind(); |
4735 | ExprResult CtorArg |
4736 | = SemaRef.BuildMemberReferenceExpr(MemberExprBase, |
4737 | ParamType, Loc, |
4738 | false, |
4739 | SS, |
4740 | SourceLocation(), |
4741 | nullptr, |
4742 | MemberLookup, |
4743 | nullptr, |
4744 | nullptr); |
4745 | if (CtorArg.isInvalid()) |
4746 | return true; |
4747 | |
4748 | |
4749 | |
4750 | |
4751 | if (RefersToRValueRef(CtorArg.get())) { |
4752 | CtorArg = CastForMoving(SemaRef, CtorArg.get()); |
4753 | } |
4754 | |
4755 | InitializedEntity Entity = |
4756 | Indirect ? InitializedEntity::InitializeMember(Indirect, nullptr, |
4757 | true) |
4758 | : InitializedEntity::InitializeMember(Field, nullptr, |
4759 | true); |
4760 | |
4761 | |
4762 | InitializationKind InitKind = |
4763 | InitializationKind::CreateDirect(Loc, SourceLocation(), SourceLocation()); |
4764 | |
4765 | Expr *CtorArgE = CtorArg.getAs<Expr>(); |
4766 | InitializationSequence InitSeq(SemaRef, Entity, InitKind, CtorArgE); |
4767 | ExprResult MemberInit = |
4768 | InitSeq.Perform(SemaRef, Entity, InitKind, MultiExprArg(&CtorArgE, 1)); |
4769 | MemberInit = SemaRef.MaybeCreateExprWithCleanups(MemberInit); |
4770 | if (MemberInit.isInvalid()) |
4771 | return true; |
4772 | |
4773 | if (Indirect) |
4774 | CXXMemberInit = new (SemaRef.Context) CXXCtorInitializer( |
4775 | SemaRef.Context, Indirect, Loc, Loc, MemberInit.getAs<Expr>(), Loc); |
4776 | else |
4777 | CXXMemberInit = new (SemaRef.Context) CXXCtorInitializer( |
4778 | SemaRef.Context, Field, Loc, Loc, MemberInit.getAs<Expr>(), Loc); |
4779 | return false; |
4780 | } |
4781 | |
4782 | assert((ImplicitInitKind == IIK_Default || ImplicitInitKind == IIK_Inherit) && |
4783 | "Unhandled implicit init kind!"); |
4784 | |
4785 | QualType FieldBaseElementType = |
4786 | SemaRef.Context.getBaseElementType(Field->getType()); |
4787 | |
4788 | if (FieldBaseElementType->isRecordType()) { |
4789 | InitializedEntity InitEntity = |
4790 | Indirect ? InitializedEntity::InitializeMember(Indirect, nullptr, |
4791 | true) |
4792 | : InitializedEntity::InitializeMember(Field, nullptr, |
4793 | true); |
4794 | InitializationKind InitKind = |
4795 | InitializationKind::CreateDefault(Loc); |
4796 | |
4797 | InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, None); |
4798 | ExprResult MemberInit = |
4799 | InitSeq.Perform(SemaRef, InitEntity, InitKind, None); |
4800 | |
4801 | MemberInit = SemaRef.MaybeCreateExprWithCleanups(MemberInit); |
4802 | if (MemberInit.isInvalid()) |
4803 | return true; |
4804 | |
4805 | if (Indirect) |
4806 | CXXMemberInit = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, |
4807 | Indirect, Loc, |
4808 | Loc, |
4809 | MemberInit.get(), |
4810 | Loc); |
4811 | else |
4812 | CXXMemberInit = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, |
4813 | Field, Loc, Loc, |
4814 | MemberInit.get(), |
4815 | Loc); |
4816 | return false; |
4817 | } |
4818 | |
4819 | if (!Field->getParent()->isUnion()) { |
4820 | if (FieldBaseElementType->isReferenceType()) { |
4821 | SemaRef.Diag(Constructor->getLocation(), |
4822 | diag::err_uninitialized_member_in_ctor) |
4823 | << (int)Constructor->isImplicit() |
4824 | << SemaRef.Context.getTagDeclType(Constructor->getParent()) |
4825 | << 0 << Field->getDeclName(); |
4826 | SemaRef.Diag(Field->getLocation(), diag::note_declared_at); |
4827 | return true; |
4828 | } |
4829 | |
4830 | if (FieldBaseElementType.isConstQualified()) { |
4831 | SemaRef.Diag(Constructor->getLocation(), |
4832 | diag::err_uninitialized_member_in_ctor) |
4833 | << (int)Constructor->isImplicit() |
4834 | << SemaRef.Context.getTagDeclType(Constructor->getParent()) |
4835 | << 1 << Field->getDeclName(); |
4836 | SemaRef.Diag(Field->getLocation(), diag::note_declared_at); |
4837 | return true; |
4838 | } |
4839 | } |
4840 | |
4841 | if (FieldBaseElementType.hasNonTrivialObjCLifetime()) { |
4842 | |
4843 | |
4844 | CXXMemberInit |
4845 | = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Field, |
4846 | Loc, Loc, |
4847 | new (SemaRef.Context) ImplicitValueInitExpr(Field->getType()), |
4848 | Loc); |
4849 | return false; |
4850 | } |
4851 | |
4852 | |
4853 | CXXMemberInit = nullptr; |
4854 | return false; |
4855 | } |
4856 | |
4857 | namespace { |
4858 | struct BaseAndFieldInfo { |
4859 | Sema &S; |
4860 | CXXConstructorDecl *Ctor; |
4861 | bool AnyErrorsInInits; |
4862 | ImplicitInitializerKind IIK; |
4863 | llvm::DenseMap<const void *, CXXCtorInitializer*> AllBaseFields; |
4864 | SmallVector<CXXCtorInitializer*, 8> AllToInit; |
4865 | llvm::DenseMap<TagDecl*, FieldDecl*> ActiveUnionMember; |
4866 | |
4867 | BaseAndFieldInfo(Sema &S, CXXConstructorDecl *Ctor, bool ErrorsInInits) |
4868 | : S(S), Ctor(Ctor), AnyErrorsInInits(ErrorsInInits) { |
4869 | bool Generated = Ctor->isImplicit() || Ctor->isDefaulted(); |
4870 | if (Ctor->getInheritedConstructor()) |
4871 | IIK = IIK_Inherit; |
4872 | else if (Generated && Ctor->isCopyConstructor()) |
4873 | IIK = IIK_Copy; |
4874 | else if (Generated && Ctor->isMoveConstructor()) |
4875 | IIK = IIK_Move; |
4876 | else |
4877 | IIK = IIK_Default; |
4878 | } |
4879 | |
4880 | bool isImplicitCopyOrMove() const { |
4881 | switch (IIK) { |
4882 | case IIK_Copy: |
4883 | case IIK_Move: |
4884 | return true; |
4885 | |
4886 | case IIK_Default: |
4887 | case IIK_Inherit: |
4888 | return false; |
4889 | } |
4890 | |
4891 | llvm_unreachable("Invalid ImplicitInitializerKind!"); |
4892 | } |
4893 | |
4894 | bool addFieldInitializer(CXXCtorInitializer *Init) { |
4895 | AllToInit.push_back(Init); |
4896 | |
4897 | |
4898 | if (Init->getInit()->HasSideEffects(S.Context)) |
4899 | S.UnusedPrivateFields.remove(Init->getAnyMember()); |
4900 | |
4901 | return false; |
4902 | } |
4903 | |
4904 | bool isInactiveUnionMember(FieldDecl *Field) { |
4905 | RecordDecl *Record = Field->getParent(); |
4906 | if (!Record->isUnion()) |
4907 | return false; |
4908 | |
4909 | if (FieldDecl *Active = |
4910 | ActiveUnionMember.lookup(Record->getCanonicalDecl())) |
4911 | return Active != Field->getCanonicalDecl(); |
4912 | |
4913 | |
4914 | if (isImplicitCopyOrMove()) |
4915 | return true; |
4916 | |
4917 | |
4918 | |
4919 | if (Field->hasInClassInitializer()) |
4920 | return false; |
4921 | |
4922 | |
4923 | if (!Field->isAnonymousStructOrUnion()) |
4924 | return true; |
4925 | CXXRecordDecl *FieldRD = Field->getType()->getAsCXXRecordDecl(); |
4926 | return !FieldRD->hasInClassInitializer(); |
4927 | } |
4928 | |
4929 | |
4930 | |
4931 | |
4932 | bool isWithinInactiveUnionMember(FieldDecl *Field, |
4933 | IndirectFieldDecl *Indirect) { |
4934 | if (!Indirect) |
4935 | return isInactiveUnionMember(Field); |
4936 | |
4937 | for (auto *C : Indirect->chain()) { |
4938 | FieldDecl *Field = dyn_cast<FieldDecl>(C); |
4939 | if (Field && isInactiveUnionMember(Field)) |
4940 | return true; |
4941 | } |
4942 | return false; |
4943 | } |
4944 | }; |
4945 | } |
4946 | |
4947 | |
4948 | |
4949 | static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) { |
4950 | if (T->isIncompleteArrayType()) |
4951 | return true; |
4952 | |
4953 | while (const ConstantArrayType *ArrayT = Context.getAsConstantArrayType(T)) { |
4954 | if (!ArrayT->getSize()) |
4955 | return true; |
4956 | |
4957 | T = ArrayT->getElementType(); |
4958 | } |
4959 | |
4960 | return false; |
4961 | } |
4962 | |
4963 | static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info, |
4964 | FieldDecl *Field, |
4965 | IndirectFieldDecl *Indirect = nullptr) { |
4966 | if (Field->isInvalidDecl()) |
4967 | return false; |
4968 | |
4969 | |
4970 | if (CXXCtorInitializer *Init = |
4971 | Info.AllBaseFields.lookup(Field->getCanonicalDecl())) |
4972 | return Info.addFieldInitializer(Init); |
4973 | |
4974 | |
4975 | |
4976 | |
4977 | |
4978 | |
4979 | |
4980 | |
4981 | |
4982 | |
4983 | |
4984 | |
4985 | |
4986 | if (Info.isWithinInactiveUnionMember(Field, Indirect)) |
4987 | return false; |
4988 | |
4989 | if (Field->hasInClassInitializer() && !Info.isImplicitCopyOrMove()) { |
4990 | ExprResult DIE = |
4991 | SemaRef.BuildCXXDefaultInitExpr(Info.Ctor->getLocation(), Field); |
4992 | if (DIE.isInvalid()) |
4993 | return true; |
4994 | |
4995 | auto Entity = InitializedEntity::InitializeMember(Field, nullptr, true); |
4996 | SemaRef.checkInitializerLifetime(Entity, DIE.get()); |
4997 | |
4998 | CXXCtorInitializer *Init; |
4999 | if (Indirect) |
5000 | Init = new (SemaRef.Context) |
5001 | CXXCtorInitializer(SemaRef.Context, Indirect, SourceLocation(), |
5002 | SourceLocation(), DIE.get(), SourceLocation()); |
5003 | else |
5004 | Init = new (SemaRef.Context) |
5005 | CXXCtorInitializer(SemaRef.Context, Field, SourceLocation(), |
5006 | SourceLocation(), DIE.get(), SourceLocation()); |
5007 | return Info.addFieldInitializer(Init); |
5008 | } |
5009 | |
5010 | |
5011 | if (isIncompleteOrZeroLengthArrayType(SemaRef.Context, Field->getType())) |
5012 | return false; |
5013 | |
5014 | |
5015 | |
5016 | |
5017 | if (Info.AnyErrorsInInits) |
5018 | return false; |
5019 | |
5020 | CXXCtorInitializer *Init = nullptr; |
5021 | if (BuildImplicitMemberInitializer(Info.S, Info.Ctor, Info.IIK, Field, |
5022 | Indirect, Init)) |
5023 | return true; |
5024 | |
5025 | if (!Init) |
5026 | return false; |
5027 | |
5028 | return Info.addFieldInitializer(Init); |
5029 | } |
5030 | |
5031 | bool |
5032 | Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor, |
5033 | CXXCtorInitializer *Initializer) { |
5034 | assert(Initializer->isDelegatingInitializer()); |
5035 | Constructor->setNumCtorInitializers(1); |
5036 | CXXCtorInitializer **initializer = |
5037 | new (Context) CXXCtorInitializer*[1]; |
5038 | memcpy(initializer, &Initializer, sizeof (CXXCtorInitializer*)); |
5039 | Constructor->setCtorInitializers(initializer); |
5040 | |
5041 | if (CXXDestructorDecl *Dtor = LookupDestructor(Constructor->getParent())) { |
5042 | MarkFunctionReferenced(Initializer->getSourceLocation(), Dtor); |
5043 | DiagnoseUseOfDecl(Dtor, Initializer->getSourceLocation()); |
5044 | } |
5045 | |
5046 | DelegatingCtorDecls.push_back(Constructor); |
5047 | |
5048 | DiagnoseUninitializedFields(*this, Constructor); |
5049 | |
5050 | return false; |
5051 | } |
5052 | |
5053 | bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors, |
5054 | ArrayRef<CXXCtorInitializer *> Initializers) { |
5055 | if (Constructor->isDependentContext()) { |
5056 | |
5057 | |
5058 | if (!Initializers.empty()) { |
5059 | Constructor->setNumCtorInitializers(Initializers.size()); |
5060 | CXXCtorInitializer **baseOrMemberInitializers = |
5061 | new (Context) CXXCtorInitializer*[Initializers.size()]; |
5062 | memcpy(baseOrMemberInitializers, Initializers.data(), |
5063 | Initializers.size() * sizeof(CXXCtorInitializer*)); |
5064 | Constructor->setCtorInitializers(baseOrMemberInitializers); |
5065 | } |
5066 | |
5067 | |
5068 | if (AnyErrors) |
5069 | Constructor->setInvalidDecl(); |
5070 | |
5071 | return false; |
5072 | } |
5073 | |
5074 | BaseAndFieldInfo Info(*this, Constructor, AnyErrors); |
5075 | |
5076 | |
5077 | |
5078 | CXXRecordDecl *ClassDecl = Constructor->getParent()->getDefinition(); |
5079 | if (!ClassDecl) |
5080 | return true; |
5081 | |
5082 | bool HadError = false; |
5083 | |
5084 | for (unsigned i = 0; i < Initializers.size(); i++) { |
5085 | CXXCtorInitializer *Member = Initializers[i]; |
5086 | |
5087 | if (Member->isBaseInitializer()) |
5088 | Info.AllBaseFields[Member->getBaseClass()->getAs<RecordType>()] = Member; |
5089 | else { |
5090 | Info.AllBaseFields[Member->getAnyMember()->getCanonicalDecl()] = Member; |
5091 | |
5092 | if (IndirectFieldDecl *F = Member->getIndirectMember()) { |
5093 | for (auto *C : F->chain()) { |
5094 | FieldDecl *FD = dyn_cast<FieldDecl>(C); |
5095 | if (FD && FD->getParent()->isUnion()) |
5096 | Info.ActiveUnionMember.insert(std::make_pair( |
5097 | FD->getParent()->getCanonicalDecl(), FD->getCanonicalDecl())); |
5098 | } |
5099 | } else if (FieldDecl *FD = Member->getMember()) { |
5100 | if (FD->getParent()->isUnion()) |
5101 | Info.ActiveUnionMember.insert(std::make_pair( |
5102 | FD->getParent()->getCanonicalDecl(), FD->getCanonicalDecl())); |
5103 | } |
5104 | } |
5105 | } |
5106 | |
5107 | |
5108 | llvm::SmallPtrSet<CXXBaseSpecifier *, 16> DirectVBases; |
5109 | for (auto &I : ClassDecl->bases()) { |
5110 | if (I.isVirtual()) |
5111 | DirectVBases.insert(&I); |
5112 | } |
5113 | |
5114 | |
5115 | for (auto &VBase : ClassDecl->vbases()) { |
5116 | if (CXXCtorInitializer *Value |
5117 | = Info.AllBaseFields.lookup(VBase.getType()->getAs<RecordType>())) { |
5118 | |
5119 | |
5120 | |
5121 | |
5122 | if (ClassDecl->isAbstract()) { |
5123 | |
5124 | |
5125 | Diag(Value->getSourceLocation(), diag::warn_abstract_vbase_init_ignored) |
5126 | << VBase.getType() << ClassDecl; |
5127 | DiagnoseAbstractType(ClassDecl); |
5128 | } |
5129 | |
5130 | Info.AllToInit.push_back(Value); |
5131 | } else if (!AnyErrors && !ClassDecl->isAbstract()) { |
5132 | |
5133 | |
5134 | |
5135 | |
5136 | bool IsInheritedVirtualBase = !DirectVBases.count(&VBase); |
5137 | CXXCtorInitializer *CXXBaseInit; |
5138 | if (BuildImplicitBaseInitializer(*this, Constructor, Info.IIK, |
5139 | &VBase, IsInheritedVirtualBase, |
5140 | CXXBaseInit)) { |
5141 | HadError = true; |
5142 | continue; |
5143 | } |
5144 | |
5145 | Info.AllToInit.push_back(CXXBaseInit); |
5146 | } |
5147 | } |
5148 | |
5149 | |
5150 | for (auto &Base : ClassDecl->bases()) { |
5151 | |
5152 | if (Base.isVirtual()) |
5153 | continue; |
5154 | |
5155 | if (CXXCtorInitializer *Value |
5156 | = Info.AllBaseFields.lookup(Base.getType()->getAs<RecordType>())) { |
5157 | Info.AllToInit.push_back(Value); |
5158 | } else if (!AnyErrors) { |
5159 | CXXCtorInitializer *CXXBaseInit; |
5160 | if (BuildImplicitBaseInitializer(*this, Constructor, Info.IIK, |
5161 | &Base, false, |
5162 | CXXBaseInit)) { |
5163 | HadError = true; |
5164 | continue; |
5165 | } |
5166 | |
5167 | Info.AllToInit.push_back(CXXBaseInit); |
5168 | } |
5169 | } |
5170 | |
5171 | |
5172 | for (auto *Mem : ClassDecl->decls()) { |
5173 | if (auto *F = dyn_cast<FieldDecl>(Mem)) { |
5174 | |
5175 | |
5176 | |
5177 | |
5178 | if (F->isUnnamedBitfield()) |
5179 | continue; |
5180 | |
5181 | |
5182 | |
5183 | |
5184 | if (F->isAnonymousStructOrUnion() && !Info.isImplicitCopyOrMove()) |
5185 | continue; |
5186 | |
5187 | if (CollectFieldInitializer(*this, Info, F)) |
5188 | HadError = true; |
5189 | continue; |
5190 | } |
5191 | |
5192 | |
5193 | if (Info.isImplicitCopyOrMove()) |
5194 | continue; |
5195 | |
5196 | if (auto *F = dyn_cast<IndirectFieldDecl>(Mem)) { |
5197 | if (F->getType()->isIncompleteArrayType()) { |
5198 | assert(ClassDecl->hasFlexibleArrayMember() && |
5199 | "Incomplete array type is not valid"); |
5200 | continue; |
5201 | } |
5202 | |
5203 | |
5204 | if (CollectFieldInitializer(*this, Info, F->getAnonField(), F)) |
5205 | HadError = true; |
5206 | |
5207 | continue; |
5208 | } |
5209 | } |
5210 | |
5211 | unsigned NumInitializers = Info.AllToInit.size(); |
5212 | if (NumInitializers > 0) { |
5213 | Constructor->setNumCtorInitializers(NumInitializers); |
5214 | CXXCtorInitializer **baseOrMemberInitializers = |
5215 | new (Context) CXXCtorInitializer*[NumInitializers]; |
5216 | memcpy(baseOrMemberInitializers, Info.AllToInit.data(), |
5217 | NumInitializers * sizeof(CXXCtorInitializer*)); |
5218 | Constructor->setCtorInitializers(baseOrMemberInitializers); |
5219 | |
5220 | |
5221 | |
5222 | MarkBaseAndMemberDestructorsReferenced(Constructor->getLocation(), |
5223 | Constructor->getParent()); |
5224 | } |
5225 | |
5226 | return HadError; |
5227 | } |
5228 | |
5229 | static void PopulateKeysForFields(FieldDecl *Field, SmallVectorImpl<const void*> &IdealInits) { |
5230 | if (const RecordType *RT = Field->getType()->getAs<RecordType>()) { |
5231 | const RecordDecl *RD = RT->getDecl(); |
5232 | if (RD->isAnonymousStructOrUnion()) { |
5233 | for (auto *Field : RD->fields()) |
5234 | PopulateKeysForFields(Field, IdealInits); |
5235 | return; |
5236 | } |
5237 | } |
5238 | IdealInits.push_back(Field->getCanonicalDecl()); |
5239 | } |
5240 | |
5241 | static const void *GetKeyForBase(ASTContext &Context, QualType BaseType) { |
5242 | return Context.getCanonicalType(BaseType).getTypePtr(); |
5243 | } |
5244 | |
5245 | static const void *GetKeyForMember(ASTContext &Context, |
5246 | CXXCtorInitializer *Member) { |
5247 | if (!Member->isAnyMemberInitializer()) |
5248 | return GetKeyForBase(Context, QualType(Member->getBaseClass(), 0)); |
5249 | |
5250 | return Member->getAnyMember()->getCanonicalDecl(); |
5251 | } |
5252 | |
5253 | static void AddInitializerToDiag(const Sema::SemaDiagnosticBuilder &Diag, |
5254 | const CXXCtorInitializer *Previous, |
5255 | const CXXCtorInitializer *Current) { |
5256 | if (Previous->isAnyMemberInitializer()) |
5257 | Diag << 0 << Previous->getAnyMember(); |
5258 | else |
5259 | Diag << 1 << Previous->getTypeSourceInfo()->getType(); |
5260 | |
5261 | if (Current->isAnyMemberInitializer()) |
5262 | Diag << 0 << Current->getAnyMember(); |
5263 | else |
5264 | Diag << 1 << Current->getTypeSourceInfo()->getType(); |
5265 | } |
5266 | |
5267 | static void DiagnoseBaseOrMemInitializerOrder( |
5268 | Sema &SemaRef, const CXXConstructorDecl *Constructor, |
5269 | ArrayRef<CXXCtorInitializer *> Inits) { |
5270 | if (Constructor->getDeclContext()->isDependentContext()) |
5271 | return; |
5272 | |
5273 | |
5274 | |
5275 | bool ShouldCheckOrder = false; |
5276 | for (unsigned InitIndex = 0; InitIndex != Inits.size(); ++InitIndex) { |
5277 | CXXCtorInitializer *Init = Inits[InitIndex]; |
5278 | if (!SemaRef.Diags.isIgnored(diag::warn_initializer_out_of_order, |
5279 | Init->getSourceLocation())) { |
5280 | ShouldCheckOrder = true; |
5281 | break; |
5282 | } |
5283 | } |
5284 | if (!ShouldCheckOrder) |
5285 | return; |
5286 | |
5287 | |
5288 | |
5289 | |
5290 | SmallVector<const void*, 32> IdealInitKeys; |
5291 | |
5292 | const CXXRecordDecl *ClassDecl = Constructor->getParent(); |
5293 | |
5294 | |
5295 | for (const auto &VBase : ClassDecl->vbases()) |
5296 | IdealInitKeys.push_back(GetKeyForBase(SemaRef.Context, VBase.getType())); |
5297 | |
5298 | |
5299 | for (const auto &Base : ClassDecl->bases()) { |
5300 | if (Base.isVirtual()) |
5301 | continue; |
5302 | IdealInitKeys.push_back(GetKeyForBase(SemaRef.Context, Base.getType())); |
5303 | } |
5304 | |
5305 | |
5306 | for (auto *Field : ClassDecl->fields()) { |
5307 | if (Field->isUnnamedBitfield()) |
5308 | continue; |
5309 | |
5310 | PopulateKeysForFields(Field, IdealInitKeys); |
5311 | } |
5312 | |
5313 | unsigned NumIdealInits = IdealInitKeys.size(); |
5314 | unsigned IdealIndex = 0; |
5315 | |
5316 | |
5317 | |
5318 | SmallVector<unsigned> WarnIndexes; |
5319 | |
5320 | |
5321 | SmallVector<std::pair<unsigned, unsigned>, 32> CorrelatedInitOrder; |
5322 | |
5323 | for (unsigned InitIndex = 0; InitIndex != Inits.size(); ++InitIndex) { |
5324 | const void *InitKey = GetKeyForMember(SemaRef.Context, Inits[InitIndex]); |
5325 | |
5326 | |
5327 | |
5328 | for (; IdealIndex != NumIdealInits; ++IdealIndex) |
5329 | if (InitKey == IdealInitKeys[IdealIndex]) |
5330 | break; |
5331 | |
5332 | |
5333 | |
5334 | |
5335 | if (IdealIndex == NumIdealInits && InitIndex) { |
5336 | WarnIndexes.push_back(InitIndex); |
5337 | |
5338 | |
5339 | for (IdealIndex = 0; IdealIndex != NumIdealInits; ++IdealIndex) |
5340 | if (InitKey == IdealInitKeys[IdealIndex]) |
5341 | break; |
5342 | |
5343 | assert(IdealIndex < NumIdealInits && |
5344 | "initializer not found in initializer list"); |
5345 | } |
5346 | CorrelatedInitOrder.emplace_back(IdealIndex, InitIndex); |
5347 | } |
5348 | |
5349 | if (WarnIndexes.empty()) |
5350 | return; |
5351 | |
5352 | |
5353 | llvm::sort(CorrelatedInitOrder, |
5354 | [](auto &LHS, auto &RHS) { return LHS.first < RHS.first; }); |
5355 | |
5356 | |
5357 | |
5358 | { |
5359 | Sema::SemaDiagnosticBuilder D = SemaRef.Diag( |
5360 | Inits[WarnIndexes.front() - 1]->getSourceLocation(), |
5361 | WarnIndexes.size() == 1 ? diag::warn_initializer_out_of_order |
5362 | : diag::warn_some_initializers_out_of_order); |
5363 | |
5364 | for (unsigned I = 0; I < CorrelatedInitOrder.size(); ++I) { |
5365 | if (CorrelatedInitOrder[I].second == I) |
5366 | continue; |
5367 | |
5368 | |
5369 | |
5370 | D << FixItHint::CreateReplacement( |
5371 | Inits[I]->getSourceRange(), |
5372 | Lexer::getSourceText( |
5373 | CharSourceRange::getTokenRange( |
5374 | Inits[CorrelatedInitOrder[I].second]->getSourceRange()), |
5375 | SemaRef.getSourceManager(), SemaRef.getLangOpts())); |
5376 | } |
5377 | |
5378 | |
5379 | |
5380 | if (WarnIndexes.size() == 1) { |
5381 | AddInitializerToDiag(D, Inits[WarnIndexes.front() - 1], |
5382 | Inits[WarnIndexes.front()]); |
5383 | return; |
5384 | } |
5385 | } |
5386 | |
5387 | |
5388 | for (unsigned WarnIndex : WarnIndexes) { |
5389 | const clang::CXXCtorInitializer *PrevInit = Inits[WarnIndex - 1]; |
5390 | auto D = SemaRef.Diag(PrevInit->getSourceLocation(), |
5391 | diag::note_initializer_out_of_order); |
5392 | AddInitializerToDiag(D, PrevInit, Inits[WarnIndex]); |
5393 | D << PrevInit->getSourceRange(); |
5394 | } |
5395 | } |
5396 | |
5397 | namespace { |
5398 | bool CheckRedundantInit(Sema &S, |
5399 | CXXCtorInitializer *Init, |
5400 | CXXCtorInitializer *&PrevInit) { |
5401 | if (!PrevInit) { |
5402 | PrevInit = Init; |
5403 | return false; |
5404 | } |
5405 | |
5406 | if (FieldDecl *Field = Init->getAnyMember()) |
5407 | S.Diag(Init->getSourceLocation(), |
5408 | diag::err_multiple_mem_initialization) |
5409 | << Field->getDeclName() |
5410 | << Init->getSourceRange(); |
5411 | else { |
5412 | const Type *BaseClass = Init->getBaseClass(); |
5413 | assert(BaseClass && "neither field nor base"); |
5414 | S.Diag(Init->getSourceLocation(), |
5415 | diag::err_multiple_base_initialization) |
5416 | << QualType(BaseClass, 0) |
5417 | << Init->getSourceRange(); |
5418 | } |
5419 | S.Diag(PrevInit->getSourceLocation(), diag::note_previous_initializer) |
5420 | << 0 << PrevInit->getSourceRange(); |
5421 | |
5422 | return true; |
5423 | } |
5424 | |
5425 | typedef std::pair<NamedDecl *, CXXCtorInitializer *> UnionEntry; |
5426 | typedef llvm::DenseMap<RecordDecl*, UnionEntry> RedundantUnionMap; |
5427 | |
5428 | bool CheckRedundantUnionInit(Sema &S, |
5429 | CXXCtorInitializer *Init, |
5430 | RedundantUnionMap &Unions) { |
5431 | FieldDecl *Field = Init->getAnyMember(); |
5432 | RecordDecl *Parent = Field->getParent(); |
5433 | NamedDecl *Child = Field; |
5434 | |
5435 | while (Parent->isAnonymousStructOrUnion() || Parent->isUnion()) { |
5436 | if (Parent->isUnion()) { |
5437 | UnionEntry &En = Unions[Parent]; |
5438 | if (En.first && En.first != Child) { |
5439 | S.Diag(Init->getSourceLocation(), |
5440 | diag::err_multiple_mem_union_initialization) |
5441 | << Field->getDeclName() |
5442 | << Init->getSourceRange(); |
5443 | S.Diag(En.second->getSourceLocation(), diag::note_previous_initializer) |
5444 | << 0 << En.second->getSourceRange(); |
5445 | return true; |
5446 | } |
5447 | if (!En.first) { |
5448 | En.first = Child; |
5449 | En.second = Init; |
5450 | } |
5451 | if (!Parent->isAnonymousStructOrUnion()) |
5452 | return false; |
5453 | } |
5454 | |
5455 | Child = Parent; |
5456 | Parent = cast<RecordDecl>(Parent->getDeclContext()); |
5457 | } |
5458 | |
5459 | return false; |
5460 | } |
5461 | } |
5462 | |
5463 | |
5464 | void Sema::ActOnMemInitializers(Decl *ConstructorDecl, |
5465 | SourceLocation ColonLoc, |
5466 | ArrayRef<CXXCtorInitializer*> MemInits, |
5467 | bool AnyErrors) { |
5468 | if (!ConstructorDecl) |
5469 | return; |
5470 | |
5471 | AdjustDeclIfTemplate(ConstructorDecl); |
5472 | |
5473 | CXXConstructorDecl *Constructor |
5474 | = dyn_cast<CXXConstructorDecl>(ConstructorDecl); |
5475 | |
5476 | if (!Constructor) { |
5477 | Diag(ColonLoc, diag::err_only_constructors_take_base_inits); |
5478 | return; |
5479 | } |
5480 | |
5481 | |
5482 | |
5483 | |
5484 | llvm::DenseMap<const void *, CXXCtorInitializer *> Members; |
5485 | |
5486 | |
5487 | RedundantUnionMap MemberUnions; |
5488 | |
5489 | bool HadError = false; |
5490 | for (unsigned i = 0; i < MemInits.size(); i++) { |
5491 | CXXCtorInitializer *Init = MemInits[i]; |
5492 | |
5493 | |
5494 | Init->setSourceOrder(i); |
5495 | |
5496 | if (Init->isAnyMemberInitializer()) { |
5497 | const void *Key = GetKeyForMember(Context, Init); |
5498 | if (CheckRedundantInit(*this, Init, Members[Key]) || |
5499 | CheckRedundantUnionInit(*this, Init, MemberUnions)) |
5500 | HadError = true; |
5501 | } else if (Init->isBaseInitializer()) { |
5502 | const void *Key = GetKeyForMember(Context, Init); |
5503 | if (CheckRedundantInit(*this, Init, Members[Key])) |
5504 | HadError = true; |
5505 | } else { |
5506 | assert(Init->isDelegatingInitializer()); |
5507 | |
5508 | if (MemInits.size() != 1) { |
5509 | Diag(Init->getSourceLocation(), |
5510 | diag::err_delegating_initializer_alone) |
5511 | << Init->getSourceRange() << MemInits[i ? 0 : 1]->getSourceRange(); |
5512 | |
5513 | } |
5514 | SetDelegatingInitializer(Constructor, MemInits[i]); |
5515 | |
5516 | return; |
5517 | } |
5518 | } |
5519 | |
5520 | if (HadError) |
5521 | return; |
5522 | |
5523 | DiagnoseBaseOrMemInitializerOrder(*this, Constructor, MemInits); |
5524 | |
5525 | SetCtorInitializers(Constructor, AnyErrors, MemInits); |
5526 | |
5527 | DiagnoseUninitializedFields(*this, Constructor); |
5528 | } |
5529 | |
5530 | void |
5531 | Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location, |
5532 | CXXRecordDecl *ClassDecl) { |
5533 | |
5534 | |
5535 | if (ClassDecl->isDependentContext() || ClassDecl->isUnion()) |
5536 | return; |
5537 | |
5538 | |
5539 | |
5540 | |
5541 | |
5542 | |
5543 | |
5544 | for (auto *Field : ClassDecl->fields()) { |
5545 | if (Field->isInvalidDecl()) |
5546 | continue; |
5547 | |
5548 | |
5549 | if (isIncompleteOrZeroLengthArrayType(Context, Field->getType())) |
5550 | continue; |
5551 | |
5552 | QualType FieldType = Context.getBaseElementType(Field->getType()); |
5553 | |
5554 | const RecordType* RT = FieldType->getAs<RecordType>(); |
5555 | if (!RT) |
5556 | continue; |
5557 | |
5558 | CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); |
5559 | if (FieldClassDecl->isInvalidDecl()) |
5560 | continue; |
5561 | if (FieldClassDecl->hasIrrelevantDestructor()) |
5562 | continue; |
5563 | |
5564 | if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion()) |
5565 | continue; |
5566 | |
5567 | CXXDestructorDecl *Dtor = LookupDestructor(FieldClassDecl); |
5568 | assert(Dtor && "No dtor found for FieldClassDecl!"); |
5569 | CheckDestructorAccess(Field->getLocation(), Dtor, |
5570 | PDiag(diag::err_access_dtor_field) |
5571 | << Field->getDeclName() |
5572 | << FieldType); |
5573 | |
5574 | MarkFunctionReferenced(Location, Dtor); |
5575 | DiagnoseUseOfDecl(Dtor, Location); |
5576 | } |
5577 | |
5578 | |
5579 | |
5580 | bool VisitVirtualBases = !ClassDecl->isAbstract(); |
5581 | |
5582 | |
5583 | |
5584 | |
5585 | if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { |
5586 | CXXDestructorDecl *Dtor = ClassDecl->getDestructor(); |
5587 | if (Dtor && Dtor->isUsed()) |
5588 | VisitVirtualBases = false; |
5589 | } |
5590 | |
5591 | llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases; |
5592 | |
5593 | |
5594 | for (const auto &Base : ClassDecl->bases()) { |
5595 | const RecordType *RT = Base.getType()->getAs<RecordType>(); |
5596 | if (!RT) |
5597 | continue; |
5598 | |
5599 | |
5600 | if (Base.isVirtual()) { |
5601 | if (!VisitVirtualBases) |
5602 | continue; |
5603 | DirectVirtualBases.insert(RT); |
5604 | } |
5605 | |
5606 | CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl()); |
5607 | |
5608 | if (BaseClassDecl->isInvalidDecl()) |
5609 | continue; |
5610 | if (BaseClassDecl->hasIrrelevantDestructor()) |
5611 | continue; |
5612 | |
5613 | CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl); |
5614 | assert(Dtor && "No dtor found for BaseClassDecl!"); |
5615 | |
5616 | |
5617 | CheckDestructorAccess(Base.getBeginLoc(), Dtor, |
5618 | PDiag(diag::err_access_dtor_base) |
5619 | << Base.getType() << Base.getSourceRange(), |
5620 | Context.getTypeDeclType(ClassDecl)); |
5621 | |
5622 | MarkFunctionReferenced(Location, Dtor); |
5623 | DiagnoseUseOfDecl(Dtor, Location); |
5624 | } |
5625 | |
5626 | if (VisitVirtualBases) |
5627 | MarkVirtualBaseDestructorsReferenced(Location, ClassDecl, |
5628 | &DirectVirtualBases); |
5629 | } |
5630 | |
5631 | void Sema::MarkVirtualBaseDestructorsReferenced( |
5632 | SourceLocation Location, CXXRecordDecl *ClassDecl, |
5633 | llvm::SmallPtrSetImpl<const RecordType *> *DirectVirtualBases) { |
5634 | |
5635 | for (const auto &VBase : ClassDecl->vbases()) { |
5636 | |
5637 | const RecordType *RT = VBase.getType()->castAs<RecordType>(); |
5638 | |
5639 | |
5640 | if (DirectVirtualBases && DirectVirtualBases->count(RT)) |
5641 | continue; |
5642 | |
5643 | CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl()); |
5644 | |
5645 | if (BaseClassDecl->isInvalidDecl()) |
5646 | continue; |
5647 | if (BaseClassDecl->hasIrrelevantDestructor()) |
5648 | continue; |
5649 | |
5650 | CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl); |
5651 | assert(Dtor && "No dtor found for BaseClassDecl!"); |
5652 | if (CheckDestructorAccess( |
5653 | ClassDecl->getLocation(), Dtor, |
5654 | PDiag(diag::err_access_dtor_vbase) |
5655 | << Context.getTypeDeclType(ClassDecl) << VBase.getType(), |
5656 | Context.getTypeDeclType(ClassDecl)) == |
5657 | AR_accessible) { |
5658 | CheckDerivedToBaseConversion( |
5659 | Context.getTypeDeclType(ClassDecl), VBase.getType(), |
5660 | diag::err_access_dtor_vbase, 0, ClassDecl->getLocation(), |
5661 | SourceRange(), DeclarationName(), nullptr); |
5662 | } |
5663 | |
5664 | MarkFunctionReferenced(Location, Dtor); |
5665 | DiagnoseUseOfDecl(Dtor, Location); |
5666 | } |
5667 | } |
5668 | |
5669 | void Sema::ActOnDefaultCtorInitializers(Decl *CDtorDecl) { |
5670 | if (!CDtorDecl) |
5671 | return; |
5672 | |
5673 | if (CXXConstructorDecl *Constructor |
5674 | = dyn_cast<CXXConstructorDecl>(CDtorDecl)) { |
5675 | SetCtorInitializers(Constructor, false); |
5676 | DiagnoseUninitializedFields(*this, Constructor); |
5677 | } |
5678 | } |
5679 | |
5680 | bool Sema::isAbstractType(SourceLocation Loc, QualType T) { |
5681 | if (!getLangOpts().CPlusPlus) |
5682 | return false; |
5683 | |
5684 | const auto *RD = Context.getBaseElementType(T)->getAsCXXRecordDecl(); |
5685 | if (!RD) |
5686 | return false; |
5687 | |
5688 | |
5689 | |
5690 | |
5691 | |
5692 | |
5693 | |
5694 | const CXXRecordDecl *Def = RD->getDefinition(); |
5695 | if (!Def || Def->isBeingDefined()) |
5696 | return false; |
5697 | |
5698 | return RD->isAbstract(); |
5699 | } |
5700 | |
5701 | bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T, |
5702 | TypeDiagnoser &Diagnoser) { |
5703 | if (!isAbstractType(Loc, T)) |
5704 | return false; |
5705 | |
5706 | T = Context.getBaseElementType(T); |
5707 | Diagnoser.diagnose(*this, Loc, T); |
5708 | DiagnoseAbstractType(T->getAsCXXRecordDecl()); |
5709 | return true; |
5710 | } |
5711 | |
5712 | void Sema::DiagnoseAbstractType(const CXXRecordDecl *RD) { |
5713 | |
5714 | |
5715 | if (PureVirtualClassDiagSet && PureVirtualClassDiagSet->count(RD)) |
5716 | return; |
5717 | |
5718 | |
5719 | |
5720 | |
5721 | if (Diags.isLastDiagnosticIgnored()) |
5722 | return; |
5723 | |
5724 | CXXFinalOverriderMap FinalOverriders; |
5725 | RD->getFinalOverriders(FinalOverriders); |
5726 | |
5727 | |
5728 | |
5729 | llvm::SmallPtrSet<const CXXMethodDecl *, 8> SeenPureMethods; |
5730 | |
5731 | for (CXXFinalOverriderMap::iterator M = FinalOverriders.begin(), |
5732 | MEnd = FinalOverriders.end(); |
5733 | M != MEnd; |
5734 | ++M) { |
5735 | for (OverridingMethods::iterator SO = M->second.begin(), |
5736 | SOEnd = M->second.end(); |
5737 | SO != SOEnd; ++SO) { |
5738 | |
5739 | |
5740 | |
5741 | |
5742 | |
5743 | |
5744 | if (SO->second.size() != 1) |
5745 | continue; |
5746 | |
5747 | if (!SO->second.front().Method->isPure()) |
5748 | continue; |
5749 | |
5750 | if (!SeenPureMethods.insert(SO->second.front().Method).second) |
5751 | continue; |
5752 | |
5753 | Diag(SO->second.front().Method->getLocation(), |
5754 | diag::note_pure_virtual_function) |
5755 | << SO->second.front().Method->getDeclName() << RD->getDeclName(); |
5756 | } |
5757 | } |
5758 | |
5759 | if (!PureVirtualClassDiagSet) |
5760 | PureVirtualClassDiagSet.reset(new RecordDeclSetTy); |
5761 | PureVirtualClassDiagSet->insert(RD); |
5762 | } |
5763 | |
5764 | namespace { |
5765 | struct AbstractUsageInfo { |
5766 | Sema &S; |
5767 | CXXRecordDecl *Record; |
5768 | CanQualType AbstractType; |
5769 | bool Invalid; |
5770 | |
5771 | AbstractUsageInfo(Sema &S, CXXRecordDecl *Record) |
5772 | : S(S), Record(Record), |
5773 | AbstractType(S.Context.getCanonicalType( |
5774 | S.Context.getTypeDeclType(Record))), |
5775 | Invalid(false) {} |
5776 | |
5777 | void DiagnoseAbstractType() { |
5778 | if (Invalid) return; |
5779 | S.DiagnoseAbstractType(Record); |
5780 | Invalid = true; |
5781 | } |
5782 | |
5783 | void CheckType(const NamedDecl *D, TypeLoc TL, Sema::AbstractDiagSelID Sel); |
5784 | }; |
5785 | |
5786 | struct CheckAbstractUsage { |
5787 | AbstractUsageInfo &Info; |
5788 | const NamedDecl *Ctx; |
5789 | |
5790 | CheckAbstractUsage(AbstractUsageInfo &Info, const NamedDecl *Ctx) |
5791 | : Info(Info), Ctx(Ctx) {} |
5792 | |
5793 | void Visit(TypeLoc TL, Sema::AbstractDiagSelID Sel) { |
5794 | switch (TL.getTypeLocClass()) { |
5795 | #define ABSTRACT_TYPELOC(CLASS, PARENT) |
5796 | #define TYPELOC(CLASS, PARENT) \ |
5797 | case TypeLoc::CLASS: Check(TL.castAs<CLASS##TypeLoc>(), Sel); break; |
5798 | #include "clang/AST/TypeLocNodes.def" |
5799 | } |
5800 | } |
5801 | |
5802 | void Check(FunctionProtoTypeLoc TL, Sema::AbstractDiagSelID Sel) { |
5803 | Visit(TL.getReturnLoc(), Sema::AbstractReturnType); |
5804 | for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) { |
5805 | if (!TL.getParam(I)) |
5806 | continue; |
5807 | |
5808 | TypeSourceInfo *TSI = TL.getParam(I)->getTypeSourceInfo(); |
5809 | if (TSI) Visit(TSI->getTypeLoc(), Sema::AbstractParamType); |
5810 | } |
5811 | } |
5812 | |
5813 | void Check(ArrayTypeLoc TL, Sema::AbstractDiagSelID Sel) { |
5814 | Visit(TL.getElementLoc(), Sema::AbstractArrayType); |
5815 | } |
5816 | |
5817 | void Check(TemplateSpecializationTypeLoc TL, Sema::AbstractDiagSelID Sel) { |
5818 | |
5819 | for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { |
5820 | TemplateArgumentLoc TAL = TL.getArgLoc(I); |
5821 | if (TAL.getArgument().getKind() == TemplateArgument::Type) |
5822 | if (TypeSourceInfo *TSI = TAL.getTypeSourceInfo()) |
5823 | Visit(TSI->getTypeLoc(), Sema::AbstractNone); |
5824 | |
5825 | } |
5826 | } |
5827 | |
5828 | |
5829 | #define CheckPolymorphic(Type) \ |
5830 | void Check(Type TL, Sema::AbstractDiagSelID Sel) { \ |
5831 | Visit(TL.getNextTypeLoc(), Sema::AbstractNone); \ |
5832 | } |
5833 | CheckPolymorphic(PointerTypeLoc) |
5834 | CheckPolymorphic(ReferenceTypeLoc) |
5835 | CheckPolymorphic(MemberPointerTypeLoc) |
5836 | CheckPolymorphic(BlockPointerTypeLoc) |
5837 | CheckPolymorphic(AtomicTypeLoc) |
5838 | |
5839 | |
5840 | |
5841 | void Check(TypeLoc TL, Sema::AbstractDiagSelID Sel) { |
5842 | |
5843 | |
5844 | |
5845 | if (TypeLoc Next = TL.getNextTypeLoc()) |
5846 | return Visit(Next, Sel); |
5847 | |
5848 | |
5849 | |
5850 | if (Sel == Sema::AbstractNone) return; |
5851 | |
5852 | |
5853 | QualType T = TL.getType(); |
5854 | if (T->isArrayType()) { |
5855 | Sel = Sema::AbstractArrayType; |
5856 | T = Info.S.Context.getBaseElementType(T); |
5857 | } |
5858 | CanQualType CT = T->getCanonicalTypeUnqualified().getUnqualifiedType(); |
5859 | if (CT != Info.AbstractType) return; |
5860 | |
5861 | |
5862 | if (Sel == Sema::AbstractArrayType) { |
5863 | Info.S.Diag(Ctx->getLocation(), diag::err_array_of_abstract_type) |
5864 | << T << TL.getSourceRange(); |
5865 | } else { |
5866 | Info.S.Diag(Ctx->getLocation(), diag::err_abstract_type_in_decl) |
5867 | << Sel << T << TL.getSourceRange(); |
5868 | } |
5869 | Info.DiagnoseAbstractType(); |
5870 | } |
5871 | }; |
5872 | |
5873 | void AbstractUsageInfo::CheckType(const NamedDecl *D, TypeLoc TL, |
5874 | Sema::AbstractDiagSelID Sel) { |
5875 | CheckAbstractUsage(*this, D).Visit(TL, Sel); |
5876 | } |
5877 | |
5878 | } |
5879 | |
5880 | |
5881 | static void CheckAbstractClassUsage(AbstractUsageInfo &Info, |
5882 | CXXMethodDecl *MD) { |
5883 | |
5884 | |
5885 | if (MD->doesThisDeclarationHaveABody()) |
5886 | return; |
5887 | |
5888 | |
5889 | |
5890 | |
5891 | if (TypeSourceInfo *TSI = MD->getTypeSourceInfo()) |
5892 | Info.CheckType(MD, TSI->getTypeLoc(), Sema::AbstractNone); |
5893 | } |
5894 | |
5895 | |
5896 | static void CheckAbstractClassUsage(AbstractUsageInfo &Info, |
5897 | CXXRecordDecl *RD) { |
5898 | for (auto *D : RD->decls()) { |
5899 | if (D->isImplicit()) continue; |
5900 | |
5901 | |
5902 | if (isa<CXXMethodDecl>(D)) { |
5903 | CheckAbstractClassUsage(Info, cast<CXXMethodDecl>(D)); |
5904 | } else if (isa<FunctionTemplateDecl>(D)) { |
5905 | FunctionDecl *FD = cast<FunctionTemplateDecl>(D)->getTemplatedDecl(); |
5906 | CheckAbstractClassUsage(Info, cast<CXXMethodDecl>(FD)); |
5907 | |
5908 | |
5909 | } else if (isa<FieldDecl>(D)) { |
5910 | FieldDecl *FD = cast<FieldDecl>(D); |
5911 | if (TypeSourceInfo *TSI = FD->getTypeSourceInfo()) |
5912 | Info.CheckType(FD, TSI->getTypeLoc(), Sema::AbstractFieldType); |
5913 | } else if (isa<VarDecl>(D)) { |
5914 | VarDecl *VD = cast<VarDecl>(D); |
5915 | if (TypeSourceInfo *TSI = VD->getTypeSourceInfo()) |
5916 | Info.CheckType(VD, TSI->getTypeLoc(), Sema::AbstractVariableType); |
5917 | |
5918 | |
5919 | } else if (isa<CXXRecordDecl>(D)) { |
5920 | CheckAbstractClassUsage(Info, cast<CXXRecordDecl>(D)); |
5921 | } else if (isa<ClassTemplateDecl>(D)) { |
5922 | CheckAbstractClassUsage(Info, |
5923 | cast<ClassTemplateDecl>(D)->getTemplatedDecl()); |
5924 | } |
5925 | } |
5926 | } |
5927 | |
5928 | static void ReferenceDllExportedMembers(Sema &S, CXXRecordDecl *Class) { |
5929 | Attr *ClassAttr = getDLLAttr(Class); |
5930 | if (!ClassAttr) |
5931 | return; |
5932 | |
5933 | assert(ClassAttr->getKind() == attr::DLLExport); |
5934 | |
5935 | TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind(); |
5936 | |
5937 | if (TSK == TSK_ExplicitInstantiationDeclaration) |
5938 | |
5939 | |
5940 | return; |
5941 | |
5942 | |
5943 | struct MarkingClassDllexported { |
5944 | Sema &S; |
5945 | MarkingClassDllexported(Sema &S, CXXRecordDecl *Class, |
5946 | SourceLocation AttrLoc) |
5947 | : S(S) { |
5948 | Sema::CodeSynthesisContext Ctx; |
5949 | Ctx.Kind = Sema::CodeSynthesisContext::MarkingClassDllexported; |
5950 | Ctx.PointOfInstantiation = AttrLoc; |
5951 | Ctx.Entity = Class; |
5952 | S.pushCodeSynthesisContext(Ctx); |
5953 | } |
5954 | ~MarkingClassDllexported() { |
5955 | S.popCodeSynthesisContext(); |
5956 | } |
5957 | } MarkingDllexportedContext(S, Class, ClassAttr->getLocation()); |
5958 | |
5959 | if (S.Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) |
5960 | S.MarkVTableUsed(Class->getLocation(), Class, true); |
5961 | |
5962 | for (Decl *Member : Class->decls()) { |
5963 | |
5964 | |
5965 | auto *VD = dyn_cast<VarDecl>(Member); |
5966 | if (VD && Member->getAttr<DLLExportAttr>() && |
5967 | VD->getStorageClass() == SC_Static && |
5968 | TSK == TSK_ImplicitInstantiation) |
5969 | S.MarkVariableReferenced(VD->getLocation(), VD); |
5970 | |
5971 | auto *MD = dyn_cast<CXXMethodDecl>(Member); |
5972 | if (!MD) |
5973 | continue; |
5974 | |
5975 | if (Member->getAttr<DLLExportAttr>()) { |
5976 | if (MD->isUserProvided()) { |
5977 | |
5978 | |
5979 | |
5980 | if (TSK == TSK_ImplicitInstantiation && !ClassAttr->isInherited()) |
5981 | continue; |
5982 | |
5983 | S.MarkFunctionReferenced(Class->getLocation(), MD); |
5984 | |
5985 | |
5986 | |
5987 | } else if (MD->isExplicitlyDefaulted()) { |
5988 | |
5989 | S.MarkFunctionReferenced(Class->getLocation(), MD); |
5990 | |
5991 | if (TSK != TSK_ExplicitInstantiationDefinition) { |
5992 | |
5993 | |
5994 | S.Consumer.HandleTopLevelDecl(DeclGroupRef(MD)); |
5995 | } |
5996 | } else if (!MD->isTrivial() || |
5997 | MD->isCopyAssignmentOperator() || |
5998 | MD->isMoveAssignmentOperator()) { |
5999 | |
6000 | |
6001 | |
6002 | |
6003 | S.MarkFunctionReferenced(Class->getLocation(), MD); |
6004 | |
6005 | |
6006 | |
6007 | S.Consumer.HandleTopLevelDecl(DeclGroupRef(MD)); |
6008 | } |
6009 | } |
6010 | } |
6011 | } |
6012 | |
6013 | static void checkForMultipleExportedDefaultConstructors(Sema &S, |
6014 | CXXRecordDecl *Class) { |
6015 | |
6016 | |
6017 | if (!S.Context.getTargetInfo().getCXXABI().isMicrosoft()) |
6018 | return; |
6019 | |
6020 | CXXConstructorDecl *LastExportedDefaultCtor = nullptr; |
6021 | for (Decl *Member : Class->decls()) { |
6022 | |
6023 | auto *CD = dyn_cast<CXXConstructorDecl>(Member); |
6024 | if (!CD || !CD->isDefaultConstructor()) |
6025 | continue; |
6026 | auto *Attr = CD->getAttr<DLLExportAttr>(); |
6027 | if (!Attr) |
6028 | continue; |
6029 | |
6030 | |
6031 | |
6032 | if (!Class->isDependentContext()) { |
6033 | for (ParmVarDecl *PD : CD->parameters()) { |
6034 | (void)S.CheckCXXDefaultArgExpr(Attr->getLocation(), CD, PD); |
6035 | S.DiscardCleanupsInEvaluationContext(); |
6036 | } |
6037 | } |
6038 | |
6039 | if (LastExportedDefaultCtor) { |
6040 | S.Diag(LastExportedDefaultCtor->getLocation(), |
6041 | diag::err_attribute_dll_ambiguous_default_ctor) |
6042 | << Class; |
6043 | S.Diag(CD->getLocation(), diag::note_entity_declared_at) |
6044 | << CD->getDeclName(); |
6045 | return; |
6046 | } |
6047 | LastExportedDefaultCtor = CD; |
6048 | } |
6049 | } |
6050 | |
6051 | static void checkCUDADeviceBuiltinSurfaceClassTemplate(Sema &S, |
6052 | CXXRecordDecl *Class) { |
6053 | bool ErrorReported = false; |
6054 | auto reportIllegalClassTemplate = [&ErrorReported](Sema &S, |
6055 | ClassTemplateDecl *TD) { |
6056 | if (ErrorReported) |
6057 | return; |
6058 | S.Diag(TD->getLocation(), |
6059 | diag::err_cuda_device_builtin_surftex_cls_template) |
6060 | << 0 << TD; |
6061 | ErrorReported = true; |
6062 | }; |
6063 | |
6064 | ClassTemplateDecl *TD = Class->getDescribedClassTemplate(); |
6065 | if (!TD) { |
6066 | auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(Class); |
6067 | if (!SD) { |
6068 | S.Diag(Class->getLocation(), |
6069 | diag::err_cuda_device_builtin_surftex_ref_decl) |
6070 | << 0 << Class; |
6071 | S.Diag(Class->getLocation(), |
6072 | diag::note_cuda_device_builtin_surftex_should_be_template_class) |
6073 | << Class; |
6074 | return; |
6075 | } |
6076 | TD = SD->getSpecializedTemplate(); |
6077 | } |
6078 | |
6079 | TemplateParameterList *Params = TD->getTemplateParameters(); |
6080 | unsigned N = Params->size(); |
6081 | |
6082 | if (N != 2) { |
6083 | reportIllegalClassTemplate(S, TD); |
6084 | S.Diag(TD->getLocation(), |
6085 | diag::note_cuda_device_builtin_surftex_cls_should_have_n_args) |
6086 | << TD << 2; |
6087 | } |
6088 | if (N > 0 && !isa<TemplateTypeParmDecl>(Params->getParam(0))) { |
6089 | reportIllegalClassTemplate(S, TD); |
6090 | S.Diag(TD->getLocation(), |
6091 | diag::note_cuda_device_builtin_surftex_cls_should_have_match_arg) |
6092 | << TD << 0 << 0; |
6093 | } |
6094 | if (N > 1) { |
6095 | auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Params->getParam(1)); |
6096 | if (!NTTP || !NTTP->getType()->isIntegralOrEnumerationType()) { |
6097 | reportIllegalClassTemplate(S, TD); |
6098 | S.Diag(TD->getLocation(), |
6099 | diag::note_cuda_device_builtin_surftex_cls_should_have_match_arg) |
6100 | << TD << 1 << 1; |
6101 | } |
6102 | } |
6103 | } |
6104 | |
6105 | static void checkCUDADeviceBuiltinTextureClassTemplate(Sema &S, |
6106 | CXXRecordDecl *Class) { |
6107 | bool ErrorReported = false; |
6108 | auto reportIllegalClassTemplate = [&ErrorReported](Sema &S, |
6109 | ClassTemplateDecl *TD) { |
6110 | if (ErrorReported) |
6111 | return; |
6112 | S.Diag(TD->getLocation(), |
6113 | diag::err_cuda_device_builtin_surftex_cls_template) |
6114 | << 1 << TD; |
6115 | ErrorReported = true; |
6116 | }; |
6117 | |
6118 | ClassTemplateDecl *TD = Class->getDescribedClassTemplate(); |
6119 | if (!TD) { |
6120 | auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(Class); |
6121 | if (!SD) { |
6122 | S.Diag(Class->getLocation(), |
6123 | diag::err_cuda_device_builtin_surftex_ref_decl) |
6124 | << 1 << Class; |
6125 | S.Diag(Class->getLocation(), |
6126 | diag::note_cuda_device_builtin_surftex_should_be_template_class) |
6127 | << Class; |
6128 | return; |
6129 | } |
6130 | TD = SD->getSpecializedTemplate(); |
6131 | } |
6132 | |
6133 | TemplateParameterList *Params = TD->getTemplateParameters(); |
6134 | unsigned N = Params->size(); |
6135 | |
6136 | if (N != 3) { |
6137 | reportIllegalClassTemplate(S, TD); |
6138 | S.Diag(TD->getLocation(), |
6139 | diag::note_cuda_device_builtin_surftex_cls_should_have_n_args) |
6140 | << TD << 3; |
6141 | } |
6142 | if (N > 0 && !isa<TemplateTypeParmDecl>(Params->getParam(0))) { |
6143 | reportIllegalClassTemplate(S, TD); |
6144 | S.Diag(TD->getLocation(), |
6145 | diag::note_cuda_device_builtin_surftex_cls_should_have_match_arg) |
6146 | << TD << 0 << 0; |
6147 | } |
6148 | if (N > 1) { |
6149 | auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Params->getParam(1)); |
6150 | if (!NTTP || !NTTP->getType()->isIntegralOrEnumerationType()) { |
6151 | reportIllegalClassTemplate(S, TD); |
6152 | S.Diag(TD->getLocatio |