summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-08-20 19:50:13 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2019-08-20 19:50:13 +0000
commit9fd495be1fb1470bfefa59938904a8f38920e0f1 (patch)
treeefbfc9920d985a6ba518f65348e610072393b4aa
parent250951abf551bd6d91fcf568739f84f046fe280a (diff)
downloadbcm5719-llvm-9fd495be1fb1470bfefa59938904a8f38920e0f1.tar.gz
bcm5719-llvm-9fd495be1fb1470bfefa59938904a8f38920e0f1.zip
[OPENMP]Fix delayed diagnostics for standalone declare target directive.
If the function is marked as declare target in a standalone directive, the delayed diagnostics is not emitted. Patch fixes this problem. llvm-svn: 369432
-rw-r--r--clang/include/clang/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/Sema.cpp6
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp19
-rw-r--r--clang/test/OpenMP/nvptx_asm_delayed_diags.c12
-rw-r--r--clang/test/OpenMP/nvptx_va_arg_delayed_diags.c13
5 files changed, 43 insertions, 10 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef94becf8df..c77429befea 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -8997,7 +8997,8 @@ private:
void popOpenMPFunctionRegion(const sema::FunctionScopeInfo *OldFSI);
/// Check whether we're allowed to call Callee from the current function.
- void checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee);
+ void checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee,
+ bool CheckForDelayedContext = true);
/// Check if the expression is allowed to be used in expressions for the
/// OpenMP devices.
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 89e7d4c9e6d..9a84a3d4c80 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1383,7 +1383,7 @@ static void emitCallStackNotes(Sema &S, FunctionDecl *FD) {
// Emit any deferred diagnostics for FD and erase them from the map in which
// they're stored.
-static void emitDeferredDiags(Sema &S, FunctionDecl *FD) {
+static void emitDeferredDiags(Sema &S, FunctionDecl *FD, bool ShowCallStack) {
auto It = S.DeviceDeferredDiags.find(FD);
if (It == S.DeviceDeferredDiags.end())
return;
@@ -1402,7 +1402,7 @@ static void emitDeferredDiags(Sema &S, FunctionDecl *FD) {
// FIXME: Should this be called after every warning/error emitted in the loop
// above, instead of just once per function? That would be consistent with
// how we handle immediate errors, but it also seems like a bit much.
- if (HasWarningOrError)
+ if (HasWarningOrError && ShowCallStack)
emitCallStackNotes(S, FD);
}
@@ -1505,7 +1505,7 @@ void Sema::markKnownEmitted(
assert(!IsKnownEmitted(S, C.Callee) &&
"Worklist should not contain known-emitted functions.");
S.DeviceKnownEmittedFns[C.Callee] = {C.Caller, C.Loc};
- emitDeferredDiags(S, C.Callee);
+ emitDeferredDiags(S, C.Callee, C.Caller);
// If this is a template instantiation, explore its callgraph as well:
// Non-dependent calls are part of the template's callgraph, while dependent
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 6d7b542ddba..9b34c888468 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1576,7 +1576,8 @@ Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
Loc, DiagID, getCurFunctionDecl(), *this);
}
-void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) {
+void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee,
+ bool CheckForDelayedContext) {
assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.");
assert(Callee && "Callee may not be null.");
@@ -1584,9 +1585,13 @@ void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) {
// If the caller is known-emitted, mark the callee as known-emitted.
// Otherwise, mark the call in our call graph so we can traverse it later.
- if (!isOpenMPDeviceDelayedContext(*this) ||
+ if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) ||
+ (!Caller && !CheckForDelayedContext) ||
(Caller && isKnownEmitted(*this, Caller)))
- markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted);
+ markKnownEmitted(*this, Caller, Callee, Loc,
+ [CheckForDelayedContext](Sema &S, FunctionDecl *FD) {
+ return CheckForDelayedContext && isKnownEmitted(S, FD);
+ });
else if (Caller)
DeviceCallGraph[Caller].insert({Callee, Loc});
}
@@ -15406,15 +15411,17 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
}
if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
D = FTD->getTemplatedDecl();
- if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+ if (auto *FD = dyn_cast<FunctionDecl>(D)) {
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
- if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
- assert(IdLoc.isValid() && "Source location is expected");
+ if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
Diag(IdLoc, diag::err_omp_function_in_link_clause);
Diag(FD->getLocation(), diag::note_defined_here) << FD;
return;
}
+ // Mark the function as must be emitted for the device.
+ if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid())
+ checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false);
}
if (auto *VD = dyn_cast<ValueDecl>(D)) {
// Problem if any with var declared with incomplete type will be reported
diff --git a/clang/test/OpenMP/nvptx_asm_delayed_diags.c b/clang/test/OpenMP/nvptx_asm_delayed_diags.c
index 460bf04b59a..3d347046e59 100644
--- a/clang/test/OpenMP/nvptx_asm_delayed_diags.c
+++ b/clang/test/OpenMP/nvptx_asm_delayed_diags.c
@@ -9,6 +9,18 @@
// expected-no-diagnostics
#endif // DIAGS
+void foo(int r) {
+#ifdef IMMEDIATE
+// expected-error@+4 {{invalid input constraint 'mx' in asm}}
+#endif // IMMEDIATE
+ __asm__("PR3908 %[lf] %[xx] %[li] %[r]"
+ : [ r ] "+r"(r)
+ : [ lf ] "mx"(0), [ li ] "mr"(0), [ xx ] "x"((double)(0)));
+}
+#ifdef IMMEDIATE
+#pragma omp declare target to(foo)
+#endif //IMMEDIATE
+
#ifdef IMMEDIATE
#pragma omp declare target
#endif //IMMEDIATE
diff --git a/clang/test/OpenMP/nvptx_va_arg_delayed_diags.c b/clang/test/OpenMP/nvptx_va_arg_delayed_diags.c
index 3420884d97b..49ab99f8eef 100644
--- a/clang/test/OpenMP/nvptx_va_arg_delayed_diags.c
+++ b/clang/test/OpenMP/nvptx_va_arg_delayed_diags.c
@@ -9,6 +9,19 @@
// expected-no-diagnostics
#endif // DIAGS
+void foo(int r, ...) {
+#ifdef IMMEDIATE
+// expected-error@+4 {{CUDA device code does not support va_arg}}
+#endif // IMMEDIATE
+ __builtin_va_list list;
+ __builtin_va_start(list, r);
+ (void)__builtin_va_arg(list, int);
+ __builtin_va_end(list);
+}
+#ifdef IMMEDIATE
+#pragma omp declare target to(foo)
+#endif //IMMEDIATE
+
#ifdef IMMEDIATE
#pragma omp declare target
#endif //IMMEDIATE
OpenPOWER on IntegriCloud