From: Matheus Izvekov Date: Thu, 2 Sep 2021 20:21:51 +0000 (+0200) Subject: [clang] fix error recovery ICE on copy elision when returing invalid variable X-Git-Tag: upstream/15.0.7~32277 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d98c34f4d7950f531661ba3f498222ccf6239a0f;p=platform%2Fupstream%2Fllvm.git [clang] fix error recovery ICE on copy elision when returing invalid variable See PR51708. Attempting copy elision in dependent contexts with invalid variable, such as a variable with incomplete type, would cause a crash when attempting to calculate it's alignment. The fix is to just skip this optimization on invalid VarDecl, as otherwise this provides no benefit to error recovery: This functionality does not try to diagnose anything, it only calculates a flag which will affect where the variable will be allocated during codegen. Signed-off-by: Matheus Izvekov Reviewed By: rtrieu Differential Revision: https://reviews.llvm.org/D109191 --- diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index d33c254..54ba12e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1087,7 +1087,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner, StartingScope, InstantiatingVarTemplate); - if (D->isNRVOVariable()) { + if (D->isNRVOVariable() && !Var->isInvalidDecl()) { QualType RT; if (auto *F = dyn_cast(DC)) RT = F->getReturnType(); diff --git a/clang/test/CXX/class/class.init/class.copy.elision/p3.cpp b/clang/test/CXX/class/class.init/class.copy.elision/p3.cpp index cd98126..7055aca 100644 --- a/clang/test/CXX/class/class.init/class.copy.elision/p3.cpp +++ b/clang/test/CXX/class/class.init/class.copy.elision/p3.cpp @@ -518,3 +518,37 @@ template X test_dependent_invalid_decl() { template X test_dependent_invalid_decl(); // expected-note {{requested here}} } // namespace test_auto_variables + +namespace PR51708 { + +class a1; // expected-note 4 {{forward declaration of 'PR51708::a1'}} +template class A2; // expected-note 4 {{template is declared here}} +using a2 = A2; + +template b f() { + // expected-error@-1 {{incomplete result type 'PR51708::a1' in function definition}} + // expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2}} + + b d; + // expected-error@-1 {{variable has incomplete type 'PR51708::a1'}} + // expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2}} + + return d; +} +template a1 f(); // expected-note-re {{in instantiation {{.*}} requested here}} +template a2 f(); // expected-note-re {{in instantiation {{.*}} requested here}} + +template b g() { + // expected-error@-1 {{incomplete result type 'PR51708::a1' in function definition}} + // expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2}} + + b d __attribute__((aligned(1))); + // expected-error@-1 {{variable has incomplete type 'PR51708::a1'}} + // expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2}} + + return d; +} +template a1 g(); // expected-note-re {{in instantiation {{.*}} requested here}} +template a2 g(); // expected-note-re {{in instantiation {{.*}} requested here}} + +} // namespace PR51708