[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