[OPENMP]Fix PR46357: Do not allow types declarations in pragmas.

Summary:
Compiler may erroneously treat current context in OpenMP pragmas as the
context where new type declaration/definition is allowed. But the
declartation/definition of the new types in OpenMP pragmas should not be
allowed.

Reviewers: jdoerfert

Subscribers: yaxunl, guansong, sstefan1, cfe-commits, caomhin

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82019
This commit is contained in:
Alexey Bataev 2020-06-17 11:02:49 -04:00
parent ce82b8e8af
commit 437cbad3b3
4 changed files with 13 additions and 4 deletions

View File

@ -294,9 +294,9 @@ namespace clang {
bool OldVal;
public:
ParsingOpenMPDirectiveRAII(Parser &P)
ParsingOpenMPDirectiveRAII(Parser &P, bool Value = true)
: P(P), OldVal(P.OpenMPDirectiveParsing) {
P.OpenMPDirectiveParsing = true;
P.OpenMPDirectiveParsing = Value;
}
/// This can be used to restore the state early, before the dtor

View File

@ -1681,7 +1681,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
Sema::TagUseKind TUK;
if (isDefiningTypeSpecifierContext(DSC) == AllowDefiningTypeSpec::No)
if (isDefiningTypeSpecifierContext(DSC) == AllowDefiningTypeSpec::No ||
(getLangOpts().OpenMP && OpenMPDirectiveParsing))
TUK = Sema::TUK_Reference;
else if (Tok.is(tok::l_brace) ||
(getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||

View File

@ -1824,6 +1824,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
// Skip last tokens.
skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
VariantMatchInfo VMI;
ASTContext &ASTCtx = Actions.getASTContext();
TI.getAsVariantMatchInfo(ASTCtx, VMI);
@ -1921,6 +1923,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
return DeclGroupPtrTy();
ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
llvm::SmallVector<Decl *, 4> Decls;
DKind = parseOpenMPDirectiveKind(*this);
while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
@ -2333,6 +2336,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
// FIXME: We create a bogus CompoundStmt scope to hold the contents of
// the captured region. Code elsewhere assumes that any FunctionScopeInfo
// should have at least one compound statement scope within it.
ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
} else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||

View File

@ -17,7 +17,11 @@ namespace N1
{
struct A { int a; A() : a(0) {} };
#pragma omp declare reduction(+: A : bar(omp_out, omp_in))
};
#pragma omp declare reduction(-: struct A : bar(omp_out, omp_in))
}
// CHECK: namespace N1 {
// CHECK: #pragma omp declare reduction (+ : N1::A : bar(omp_out, omp_in))
// CHECK: #pragma omp declare reduction (- : struct A : bar(omp_out, omp_in))
#pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
// CHECK: #pragma omp declare reduction (+ : int : omp_out *= omp_in){{$}}