Skip to content

Commit d98c34f

Browse files
committed
[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 <[email protected]> Reviewed By: rtrieu Differential Revision: https://reviews.llvm.org/D109191
1 parent d0c0647 commit d98c34f

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D,
10871087

10881088
SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner,
10891089
StartingScope, InstantiatingVarTemplate);
1090-
if (D->isNRVOVariable()) {
1090+
if (D->isNRVOVariable() && !Var->isInvalidDecl()) {
10911091
QualType RT;
10921092
if (auto *F = dyn_cast<FunctionDecl>(DC))
10931093
RT = F->getReturnType();

clang/test/CXX/class/class.init/class.copy.elision/p3.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,3 +518,37 @@ template <class T> X<T> test_dependent_invalid_decl() {
518518
template X<int> test_dependent_invalid_decl<int>(); // expected-note {{requested here}}
519519

520520
} // namespace test_auto_variables
521+
522+
namespace PR51708 {
523+
524+
class a1; // expected-note 4 {{forward declaration of 'PR51708::a1'}}
525+
template <class> class A2; // expected-note 4 {{template is declared here}}
526+
using a2 = A2<int>;
527+
528+
template <class b> b f() {
529+
// expected-error@-1 {{incomplete result type 'PR51708::a1' in function definition}}
530+
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
531+
532+
b d;
533+
// expected-error@-1 {{variable has incomplete type 'PR51708::a1'}}
534+
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
535+
536+
return d;
537+
}
538+
template a1 f<a1>(); // expected-note-re {{in instantiation {{.*}} requested here}}
539+
template a2 f<a2>(); // expected-note-re {{in instantiation {{.*}} requested here}}
540+
541+
template <class b> b g() {
542+
// expected-error@-1 {{incomplete result type 'PR51708::a1' in function definition}}
543+
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
544+
545+
b d __attribute__((aligned(1)));
546+
// expected-error@-1 {{variable has incomplete type 'PR51708::a1'}}
547+
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
548+
549+
return d;
550+
}
551+
template a1 g<a1>(); // expected-note-re {{in instantiation {{.*}} requested here}}
552+
template a2 g<a2>(); // expected-note-re {{in instantiation {{.*}} requested here}}
553+
554+
} // namespace PR51708

0 commit comments

Comments
 (0)