[clang] 150f7ce - Referencing a static function defined in an opnemp clause, is

Zahira Ammarguellat via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 11 06:56:13 PDT 2021


Author: Zahira Ammarguellat
Date: 2021-06-11T06:56:01-07:00
New Revision: 150f7cedfb2e072804f4a0887d14c97a7fe3f374

URL: https://github.com/llvm/llvm-project/commit/150f7cedfb2e072804f4a0887d14c97a7fe3f374
DIFF: https://github.com/llvm/llvm-project/commit/150f7cedfb2e072804f4a0887d14c97a7fe3f374.diff

LOG: Referencing a static function defined in an opnemp clause, is
generating an erroneous warning.

See here: https://godbolt.org/z/ajKPc36M7

Added: 
    clang/test/OpenMP/declare_variant.cpp

Modified: 
    clang/lib/Sema/Sema.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 8fd4c680d3bff..850c189cc51a3 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<VarDecl>(VD) << VD;
+      bool IsImplicitBase = false;
+      if (const auto *BaseD = dyn_cast<FunctionDecl>(VD)) {
+        auto *DVAttr = BaseD->getAttr<OMPDeclareVariantAttr>();
+        if (DVAttr && !DVAttr->getTraitInfo().isExtensionActive(
+                          llvm::omp::TraitProperty::
+                              implementation_extension_disable_implicit_base)) {
+          const auto *Func = cast<FunctionDecl>(
+              cast<DeclRefExpr>(DVAttr->getVariantFuncRef())->getDecl());
+          IsImplicitBase = BaseD->isImplicit() &&
+                           Func->getIdentifier()->isMangledOpenMPVariantName();
+        }
+      }
+      if (!S.getLangOpts().OpenMP || !IsImplicitBase)
+        S.Diag(VD->getLocation(), diag::warn_undefined_internal)
+            << isa<VarDecl>(VD) << VD;
     } else if (auto *FD = dyn_cast<FunctionDecl>(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 0000000000000..86d0b5c7d81a1
--- /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 at +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 at +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 at +1{{used here}}
+  baz();
+  // expected-note at +1{{used here}}
+  bar();
+
+  return 0;
+}


        


More information about the cfe-commits mailing list