[llvm-branch-commits] [clang] c30b281 - [clang] fix error recovery ICE on copy elision when returing invalid variable
Tom Stellard via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 7 10:45:46 PDT 2021
Author: Matheus Izvekov
Date: 2021-09-07T10:45:35-07:00
New Revision: c30b2813a1d522eb9adeec2d73b1e79a8020c998
URL: https://github.com/llvm/llvm-project/commit/c30b2813a1d522eb9adeec2d73b1e79a8020c998
DIFF: https://github.com/llvm/llvm-project/commit/c30b2813a1d522eb9adeec2d73b1e79a8020c998.diff
LOG: [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 <mizvekov at gmail.com>
Reviewed By: rtrieu
Differential Revision: https://reviews.llvm.org/D109191
(cherry picked from commit d98c34f4d7950f531661ba3f498222ccf6239a0f)
Added:
Modified:
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/test/CXX/class/class.init/class.copy.elision/p3.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index be4c519307898..25f1348687581 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<FunctionDecl>(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 cd981264c9b69..7055acad6ccf9 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 <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 at -1 {{incomplete result type 'PR51708::a1' in function definition}}
+ // expected-error at -2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
+
+ b d;
+ // expected-error at -1 {{variable has incomplete type 'PR51708::a1'}}
+ // expected-error at -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 at -1 {{incomplete result type 'PR51708::a1' in function definition}}
+ // expected-error at -2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
+
+ b d __attribute__((aligned(1)));
+ // expected-error at -1 {{variable has incomplete type 'PR51708::a1'}}
+ // expected-error at -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
More information about the llvm-branch-commits
mailing list