From 150f7cedfb2e072804f4a0887d14c97a7fe3f374 Mon Sep 17 00:00:00 2001 From: Zahira Ammarguellat Date: Wed, 2 Jun 2021 07:59:07 -0700 Subject: [PATCH] Referencing a static function defined in an opnemp clause, is generating an erroneous warning. See here: https://godbolt.org/z/ajKPc36M7 --- clang/lib/Sema/Sema.cpp | 17 +++++++++++++++-- clang/test/OpenMP/declare_variant.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 clang/test/OpenMP/declare_variant.cpp diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 8fd4c68..850c189 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -812,8 +812,21 @@ static void checkUndefinedButUsed(Sema &S) { // FIXME: We can promote this to an error. The function or variable can't // be defined anywhere else, so the program must necessarily violate the // one definition rule. - S.Diag(VD->getLocation(), diag::warn_undefined_internal) - << isa(VD) << VD; + bool IsImplicitBase = false; + if (const auto *BaseD = dyn_cast(VD)) { + auto *DVAttr = BaseD->getAttr(); + if (DVAttr && !DVAttr->getTraitInfo().isExtensionActive( + llvm::omp::TraitProperty:: + implementation_extension_disable_implicit_base)) { + const auto *Func = cast( + cast(DVAttr->getVariantFuncRef())->getDecl()); + IsImplicitBase = BaseD->isImplicit() && + Func->getIdentifier()->isMangledOpenMPVariantName(); + } + } + if (!S.getLangOpts().OpenMP || !IsImplicitBase) + S.Diag(VD->getLocation(), diag::warn_undefined_internal) + << isa(VD) << VD; } else if (auto *FD = dyn_cast(VD)) { (void)FD; assert(FD->getMostRecentDecl()->isInlined() && diff --git a/clang/test/OpenMP/declare_variant.cpp b/clang/test/OpenMP/declare_variant.cpp new file mode 100644 index 0000000..86d0b5c --- /dev/null +++ b/clang/test/OpenMP/declare_variant.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify %s + +namespace { +// TODO this must be fixed. This warning shouldn't be generated. +// expected-warning@+1{{function '(anonymous namespace)::bar' has internal linkage but is not defined}} +void bar(); +} // namespace + +#pragma omp begin declare variant match(user = {condition(1)}) +void bar() { +} +#pragma omp end declare variant + +// expected-warning@+1{{function 'baz' has internal linkage but is not defined}} +static void baz(); +#pragma omp begin declare variant match(device = {kind(nohost)}) +static void baz() {} +#pragma omp end declare variant + +#pragma omp begin declare variant match(device = {kind(host)}) +static void foo() {} +#pragma omp end declare variant + +int main() { + foo(); + // expected-note@+1{{used here}} + baz(); + // expected-note@+1{{used here}} + bar(); + + return 0; +} -- 2.7.4