InGroup<OpenMPTarget>;
def err_omp_declare_variant_incompat_attributes : Error<
"'#pragma omp declare variant' is not compatible with any target-specific attributes">;
-def err_omp_declare_variant_after_used : Error<
+def warn_omp_declare_variant_after_used : Warning<
"'#pragma omp declare variant' cannot be applied for function after first "
- "usage">;
+ "usage; the original function might be used">, InGroup<SourceUsesOpenMP>;
+def warn_omp_declare_variant_after_emitted : Warning<
+ "'#pragma omp declare variant' cannot be applied to the function that was defined already;"
+ " the original function might be used">, InGroup<SourceUsesOpenMP>;
def err_omp_declare_variant_noproto : Error<
"function with '#pragma omp declare variant' must have a prototype">;
def note_omp_declare_variant_specified_here : Note<
}
// Allow #pragma omp declare variant only if the function is not used.
- if (FD->isUsed(false)) {
- Diag(SR.getBegin(), diag::err_omp_declare_variant_after_used)
+ if (FD->isUsed(false))
+ Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
+ << FD->getLocation();
+
+ // Check if the function was emitted already.
+ if ((LangOpts.EmitAllDecls && FD->isDefined()) ||
+ Context.DeclMustBeEmitted(FD))
+ Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
<< FD->getLocation();
- return None;
- }
// The VariantRef must point to function.
if (!VariantRef) {
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++14 -fexceptions -fcxx-exceptions %s -ast-print -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++14 -fexceptions -fcxx-exceptions %s -ast-print -o - -Wno-source-uses-openmp | FileCheck %s
-// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++14 -fexceptions -fcxx-exceptions %s -ast-print -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++14 -fexceptions -fcxx-exceptions %s -ast-print -o - -Wno-source-uses-openmp | FileCheck %s
// expected-no-diagnostics
return after_use();
}
-// expected-error@+1 {{'#pragma omp declare variant' cannot be applied for function after first usage}}
+// expected-warning@+1 {{'#pragma omp declare variant' cannot be applied for function after first usage; the original function might be used}}
#pragma omp declare variant(after_use_variant) match(xxx={})
int after_use(void);
+// expected-warning@+1 {{#pragma omp declare variant' cannot be applied to the function that was defined already; the original function might be used}}
+#pragma omp declare variant(after_use_variant) match(xxx={})
+int defined(void) { return 0; }
int diff_cc_variant(void);
// expected-error@+1 {{function with '#pragma omp declare variant' has a different calling convention}}
// expected-error@+1 {{variant in '#pragma omp declare variant' with type '<overloaded function type>' is incompatible with type 'void (*)(int *, int *, int *, int *)'}}
#pragma omp declare variant(barbar <int>) match(xxx = {})
template <>
-void h(int *hp, int *hp2, int *hq, int *lin) {
- h((float *)hp, (float *)hp2, (float *)hq, (float *)lin);
-}
+void h(int *hp, int *hp2, int *hq, int *lin);
int after_use_variant(void);
int after_use();
return after_use();
}
-// expected-error@+1 {{'#pragma omp declare variant' cannot be applied for function after first usage}}
+// expected-warning@+1 {{'#pragma omp declare variant' cannot be applied for function after first usage; the original function might be used}}
#pragma omp declare variant(after_use_variant) match(xxx = {})
int after_use(void);
int fn_deduced();
int fn_deduced_variant1();
+// expected-warning@+1 {{'#pragma omp declare variant' cannot be applied to the function that was defined already; the original function might be used}}
#pragma omp declare variant(fn_deduced_variant1) match(xxx = {})
auto fn_deduced1() { return 0; }