Skip to content

Commit

Permalink
[clang] fix error recovery ICE on copy elision when returing invalid …
Browse files Browse the repository at this point in the history
…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 <mizvekov@gmail.com>

Reviewed By: rtrieu

Differential Revision: https://reviews.llvm.org/D109191

(cherry picked from commit d98c34f)
  • Loading branch information
mizvekov authored and tstellar committed Sep 7, 2021
1 parent 6668e31 commit c30b281
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<FunctionDecl>(DC))
RT = F->getReturnType();
Expand Down
34 changes: 34 additions & 0 deletions clang/test/CXX/class/class.init/class.copy.elision/p3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,3 +518,37 @@ template <class T> X<T> test_dependent_invalid_decl() {
template X<int> test_dependent_invalid_decl<int>(); // expected-note {{requested here}}

} // namespace test_auto_variables

namespace PR51708 {

class a1; // expected-note 4 {{forward declaration of 'PR51708::a1'}}
template <class> class A2; // expected-note 4 {{template is declared here}}
using a2 = A2<int>;

template <class b> b f() {
// expected-error@-1 {{incomplete result type 'PR51708::a1' in function definition}}
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}

b d;
// expected-error@-1 {{variable has incomplete type 'PR51708::a1'}}
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}

return d;
}
template a1 f<a1>(); // expected-note-re {{in instantiation {{.*}} requested here}}
template a2 f<a2>(); // expected-note-re {{in instantiation {{.*}} requested here}}

template <class b> b g() {
// expected-error@-1 {{incomplete result type 'PR51708::a1' in function definition}}
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}

b d __attribute__((aligned(1)));
// expected-error@-1 {{variable has incomplete type 'PR51708::a1'}}
// expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}

return d;
}
template a1 g<a1>(); // expected-note-re {{in instantiation {{.*}} requested here}}
template a2 g<a2>(); // expected-note-re {{in instantiation {{.*}} requested here}}

} // namespace PR51708

0 comments on commit c30b281

Please sign in to comment.