diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2019-08-20 19:50:13 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2019-08-20 19:50:13 +0000 |
commit | e1407069084cbde11c3b6ae93a1435f11c294675 (patch) | |
tree | 0dcd003e3b5ab3788b54400d3bb3235e0c0335e4 /lib/Sema | |
parent | 17542ec9635e5c652b03ad865a12eac34cb3e8c1 (diff) | |
download | clang-e1407069084cbde11c3b6ae93a1435f11c294675.tar.gz |
[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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@369432 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 19 |
2 files changed, 16 insertions, 9 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 89e7d4c9e6..9a84a3d4c8 100644 --- a/lib/Sema/Sema.cpp +++ b/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/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 6d7b542ddb..9b34c88846 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/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 |