[clang] a913e87 - [OPENMP]Fix PR44133: crash on lambda reductions in templates.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 26 07:58:52 PST 2019
Author: Alexey Bataev
Date: 2019-11-26T10:55:54-05:00
New Revision: a913e872d6e7044ae77e55c45ab3ea5304eb7262
URL: https://github.com/llvm/llvm-project/commit/a913e872d6e7044ae77e55c45ab3ea5304eb7262
DIFF: https://github.com/llvm/llvm-project/commit/a913e872d6e7044ae77e55c45ab3ea5304eb7262.diff
LOG: [OPENMP]Fix PR44133: crash on lambda reductions in templates.
Need to perform the instantiation of the combiner/initializer even if
the resulting type is not dependent, if the construct is defined in
templates in some cases.
Added:
clang/test/OpenMP/declare_reduction_codegen_in_templates.cpp
Modified:
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 63777d5272b7..a2fd8a92dd61 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3067,6 +3067,17 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
} else {
SubstReductionType = D->getType();
}
+ Expr *Combiner = D->getCombiner();
+ Expr *Init = D->getInitializer();
+ const bool CombinerRequiresInstantiation =
+ Combiner &&
+ (Combiner->isValueDependent() || Combiner->isInstantiationDependent() ||
+ Combiner->isTypeDependent() ||
+ Combiner->containsUnexpandedParameterPack());
+ const bool InitRequiresInstantiation =
+ Init &&
+ (Init->isValueDependent() || Init->isInstantiationDependent() ||
+ Init->isTypeDependent() || Init->containsUnexpandedParameterPack());
if (SubstReductionType.isNull())
return nullptr;
bool IsCorrect = !SubstReductionType.isNull();
@@ -3084,11 +3095,12 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
PrevDeclInScope);
auto *NewDRD = cast<OMPDeclareReductionDecl>(DRD.get().getSingleDecl());
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDRD);
- if (!RequiresInstantiation) {
- if (Expr *Combiner = D->getCombiner()) {
+ if (!RequiresInstantiation && !CombinerRequiresInstantiation &&
+ !InitRequiresInstantiation) {
+ if (Combiner) {
NewDRD->setCombinerData(D->getCombinerIn(), D->getCombinerOut());
NewDRD->setCombiner(Combiner);
- if (Expr *Init = D->getInitializer()) {
+ if (Init) {
NewDRD->setInitializerData(D->getInitOrig(), D->getInitPriv());
NewDRD->setInitializer(Init, D->getInitializerKind());
}
@@ -3100,22 +3112,32 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
Expr *SubstCombiner = nullptr;
Expr *SubstInitializer = nullptr;
// Combiners instantiation sequence.
- if (D->getCombiner()) {
- SemaRef.ActOnOpenMPDeclareReductionCombinerStart(
- /*S=*/nullptr, NewDRD);
- SemaRef.CurrentInstantiationScope->InstantiatedLocal(
- cast<DeclRefExpr>(D->getCombinerIn())->getDecl(),
- cast<DeclRefExpr>(NewDRD->getCombinerIn())->getDecl());
- SemaRef.CurrentInstantiationScope->InstantiatedLocal(
- cast<DeclRefExpr>(D->getCombinerOut())->getDecl(),
- cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl());
- auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
- Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
- ThisContext);
- SubstCombiner = SemaRef.SubstExpr(D->getCombiner(), TemplateArgs).get();
- SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner);
- // Initializers instantiation sequence.
- if (D->getInitializer()) {
+ if (Combiner) {
+ if (!CombinerRequiresInstantiation) {
+ NewDRD->setCombinerData(D->getCombinerIn(), D->getCombinerOut());
+ NewDRD->setCombiner(Combiner);
+ } else {
+ SemaRef.ActOnOpenMPDeclareReductionCombinerStart(
+ /*S=*/nullptr, NewDRD);
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(
+ cast<DeclRefExpr>(D->getCombinerIn())->getDecl(),
+ cast<DeclRefExpr>(NewDRD->getCombinerIn())->getDecl());
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(
+ cast<DeclRefExpr>(D->getCombinerOut())->getDecl(),
+ cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl());
+ auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
+ Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
+ ThisContext);
+ SubstCombiner = SemaRef.SubstExpr(Combiner, TemplateArgs).get();
+ SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner);
+ }
+ }
+ // Initializers instantiation sequence.
+ if (Init) {
+ if (!InitRequiresInstantiation) {
+ NewDRD->setInitializerData(D->getInitOrig(), D->getInitPriv());
+ NewDRD->setInitializer(Init, D->getInitializerKind());
+ } else {
VarDecl *OmpPrivParm =
SemaRef.ActOnOpenMPDeclareReductionInitializerStart(
/*S=*/nullptr, NewDRD);
@@ -3126,8 +3148,7 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
cast<DeclRefExpr>(D->getInitPriv())->getDecl(),
cast<DeclRefExpr>(NewDRD->getInitPriv())->getDecl());
if (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit) {
- SubstInitializer =
- SemaRef.SubstExpr(D->getInitializer(), TemplateArgs).get();
+ SubstInitializer = SemaRef.SubstExpr(Init, TemplateArgs).get();
} else {
auto *OldPrivParm =
cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl());
@@ -3139,19 +3160,17 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
SemaRef.ActOnOpenMPDeclareReductionInitializerEnd(
NewDRD, SubstInitializer, OmpPrivParm);
}
- IsCorrect =
- IsCorrect && SubstCombiner &&
- (!D->getInitializer() ||
- (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit &&
- SubstInitializer) ||
- (D->getInitializerKind() != OMPDeclareReductionDecl::CallInit &&
- !SubstInitializer && !SubstInitializer));
- } else {
- IsCorrect = false;
}
+ IsCorrect = IsCorrect && (!CombinerRequiresInstantiation || SubstCombiner) &&
+ (!InitRequiresInstantiation ||
+ (!Init ||
+ (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit &&
+ SubstInitializer) ||
+ (D->getInitializerKind() != OMPDeclareReductionDecl::CallInit &&
+ !SubstInitializer)));
- (void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(/*S=*/nullptr, DRD,
- IsCorrect);
+ (void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(
+ /*S=*/nullptr, DRD, IsCorrect && !D->isInvalidDecl());
return NewDRD;
}
diff --git a/clang/test/OpenMP/declare_reduction_codegen_in_templates.cpp b/clang/test/OpenMP/declare_reduction_codegen_in_templates.cpp
new file mode 100644
index 000000000000..0409c0219144
--- /dev/null
+++ b/clang/test/OpenMP/declare_reduction_codegen_in_templates.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++17 -emit-llvm %s -triple x86_64-linux -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++17 -triple x86_64-linux -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-linux -fexceptions -fcxx-exceptions -std=c++17 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++17 -emit-llvm %s -triple x86_64-linux -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++17 -triple x86_64-linux -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
+// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-linux -fexceptions -fcxx-exceptions -std=c++17 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s
+// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
+// expected-no-diagnostics
+
+// CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @{{.+}}, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[STD_D:%.+]]*)* [[OUTLINED:@.+]] to void (i32*, i32*, ...)*), [[STD_D]]* %{{.+}})
+
+// CHECK: define internal void [[OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, [[STD_D]]* {{.+}})
+// CHECK: call i32 @__kmpc_reduce_nowait(%struct.ident_t*
+
+#ifndef HEADER
+#define HEADER
+
+typedef long unsigned a;
+namespace std {
+template <class> class initializer_list {
+ const int *b;
+ a c;
+};
+template <typename, typename> class d {};
+template <typename e> class f {
+public:
+ f(initializer_list<e>);
+};
+} // namespace std
+template <class g, class h> void foo(g, h) {
+ std::d<a, double> i;
+#pragma omp declare reduction(j : std::d <a, double> : []{}())
+#pragma omp parallel reduction(j : i)
+ ;
+}
+void k() {
+ std::f<int> l{};
+ std::f<int> m{2};
+ foo(l, m);
+}
+
+#endif // HEADER
More information about the cfe-commits
mailing list