From 74a04e80c86cfe4b7e138b01fb0a0efd9b1ea5a2 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 13 Mar 2019 19:31:34 +0000 Subject: [PATCH] [OPENMP]Disable ADL in C for user-defined reductions. C does not support ADL, disable it for C to prevent compiler crash. llvm-svn: 356089 --- clang/lib/Sema/SemaOpenMP.cpp | 60 +++++++++++++------------- clang/test/OpenMP/declare_reduction_messages.c | 10 +++++ 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 68ee887..fbbef37 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -10958,35 +10958,37 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, } } // Perform ADL. - argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); - if (auto *VD = filterLookupForUDReductionAndMapper( - Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { - if (!D->isInvalidDecl() && - SemaRef.Context.hasSameType(D->getType(), Ty)) - return D; - return nullptr; - })) - return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), - VK_LValue, Loc); - if (auto *VD = filterLookupForUDReductionAndMapper( - Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { - if (!D->isInvalidDecl() && - SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && - !Ty.isMoreQualifiedThan(D->getType())) - return D; - return nullptr; - })) { - CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, - /*DetectVirtual=*/false); - if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { - if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( - VD->getType().getUnqualifiedType()))) { - if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), - /*DiagID=*/0) != - Sema::AR_inaccessible) { - SemaRef.BuildBasePathArray(Paths, BasePath); - return SemaRef.BuildDeclRefExpr( - VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); + if (SemaRef.getLangOpts().CPlusPlus) { + argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); + if (auto *VD = filterLookupForUDReductionAndMapper( + Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { + if (!D->isInvalidDecl() && + SemaRef.Context.hasSameType(D->getType(), Ty)) + return D; + return nullptr; + })) + return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), + VK_LValue, Loc); + if (auto *VD = filterLookupForUDReductionAndMapper( + Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { + if (!D->isInvalidDecl() && + SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && + !Ty.isMoreQualifiedThan(D->getType())) + return D; + return nullptr; + })) { + CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, + /*DetectVirtual=*/false); + if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { + if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( + VD->getType().getUnqualifiedType()))) { + if (SemaRef.CheckBaseClassAccess( + Loc, VD->getType(), Ty, Paths.front(), + /*DiagID=*/0) != Sema::AR_inaccessible) { + SemaRef.BuildBasePathArray(Paths, BasePath); + return SemaRef.BuildDeclRefExpr( + VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); + } } } } diff --git a/clang/test/OpenMP/declare_reduction_messages.c b/clang/test/OpenMP/declare_reduction_messages.c index 39387c7..27e9e6e 100644 --- a/clang/test/OpenMP/declare_reduction_messages.c +++ b/clang/test/OpenMP/declare_reduction_messages.c @@ -41,7 +41,17 @@ int temp; // expected-note 6 {{'temp' declared here}} #pragma omp declare reduction(fun8 : long : omp_out += omp_in) initializer(omp_priv = 23)) // expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} expected-error {{redefinition of user-defined reduction for type 'long'}} #pragma omp declare reduction(fun9 : long : omp_out += omp_in) initializer(omp_priv = ) // expected-error {{expected expression}} +struct S { + int s; +}; +#pragma omp declare reduction(+: struct S: omp_out.s += omp_in.s) // initializer(omp_priv = { .s = 0 }) + int fun(int arg) { + struct S s;// expected-note {{'s' defined here}} + s.s = 0; +#pragma omp parallel for reduction(+ : s) // expected-error {{list item of type 'struct S' is not valid for specified reduction operation: unable to provide default initialization value}} + for (arg = 0; arg < 10; ++arg) + s.s += arg; #pragma omp declare reduction(red : int : omp_out++) { #pragma omp declare reduction(red : int : omp_out++) // expected-note {{previous definition is here}} -- 2.7.4