diff options
-rw-r--r-- | clang/include/clang/Sema/Scope.h | 8 | ||||
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 8 | ||||
-rw-r--r-- | clang/test/Sema/implicit-decl-c90.c | 39 | ||||
-rw-r--r-- | clang/test/Sema/implicit-decl.c | 5 |
14 files changed, 103 insertions, 36 deletions
diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h index d0b006b82ec..e892d8205b5 100644 --- a/clang/include/clang/Sema/Scope.h +++ b/clang/include/clang/Sema/Scope.h @@ -124,6 +124,9 @@ public: /// We are currently in the filter expression of an SEH except block. SEHFilterScope = 0x200000, + + /// This is a compound statement scope. + CompoundStmtScope = 0x400000, }; private: /// The parent scope for this scope. This is null for the translation-unit @@ -429,6 +432,11 @@ public: /// \brief Determine whether this scope is a SEH '__except' block. bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; } + /// \brief Determine whether this scope is a compound statement scope. + bool isCompoundStmtScope() const { + return getFlags() & Scope::CompoundStmtScope; + } + /// \brief Returns if rhs has a higher scope depth than this. /// /// The caller is responsible for calling this only if one of the two scopes diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index b68559485a5..c9a895d7d54 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -518,7 +518,8 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { // Parse the method body. Function body parsing code is similar enough // to be re-used for method bodies as well. - ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope); + ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope); Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D); if (Tok.is(tok::kw_try)) { diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index a4610698c46..f6a315198c3 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1388,7 +1388,9 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, // If the Decl is on a function, add function parameters to the scope. bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); - ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope); + ParseScope FnScope( + this, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope, + HasFunScope); if (HasFunScope) Actions.ActOnReenterFunctionContext(Actions.CurScope, D); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 44b87af01ab..f4cdc2201af 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2881,7 +2881,7 @@ ExprResult Parser::ParseBlockLiteralExpression() { // allows determining whether a variable reference inside the block is // within or outside of the block. ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope | - Scope::DeclScope); + Scope::CompoundStmtScope | Scope::DeclScope); // Inform sema that we are starting a block. Actions.ActOnBlockStart(CaretLoc, getCurScope()); diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index dcafbadae5c..56b03279957 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1281,7 +1281,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using // it. - unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope; + unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope; ParseScope BodyScope(this, ScopeFlags); Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope()); diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 01b1bf48e47..edf1da171b0 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -2478,7 +2478,7 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.get()); // Parse the compound statement within a new scope. - ParseScope bodyScope(this, Scope::DeclScope); + ParseScope bodyScope(this, Scope::DeclScope | Scope::CompoundStmtScope); StmtResult body(ParseCompoundStatementBody()); bodyScope.Exit(); @@ -2514,7 +2514,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { } StmtVector CatchStmts; StmtResult FinallyStmt; - ParseScope TryScope(this, Scope::DeclScope); + ParseScope TryScope(this, Scope::DeclScope | Scope::CompoundStmtScope); StmtResult TryBody(ParseCompoundStatementBody()); TryScope.Exit(); if (TryBody.isInvalid()) @@ -2535,7 +2535,9 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { ConsumeToken(); // consume catch if (Tok.is(tok::l_paren)) { ConsumeParen(); - ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope); + ParseScope CatchScope(this, Scope::DeclScope | + Scope::CompoundStmtScope | + Scope::AtCatchScope); if (Tok.isNot(tok::ellipsis)) { DeclSpec DS(AttrFactory); ParseDeclarationSpecifiers(DS); @@ -2579,7 +2581,8 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { } else { assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?"); ConsumeToken(); // consume finally - ParseScope FinallyScope(this, Scope::DeclScope); + ParseScope FinallyScope(this, + Scope::DeclScope | Scope::CompoundStmtScope); StmtResult FinallyBody(true); if (Tok.is(tok::l_brace)) @@ -2616,7 +2619,7 @@ Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) { } // Enter a scope to hold everything within the compound stmt. Compound // statements can always hold declarations. - ParseScope BodyScope(this, Scope::DeclScope); + ParseScope BodyScope(this, Scope::DeclScope | Scope::CompoundStmtScope); StmtResult AutoreleasePoolBody(ParseCompoundStatementBody()); @@ -3650,11 +3653,10 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { assert(Tok.isOneOf(tok::l_brace, tok::kw_try, tok::colon) && "Inline objective-c method not starting with '{' or 'try' or ':'"); // Enter a scope for the method or c-function body. - ParseScope BodyScope(this, - parseMethod - ? Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope - : Scope::FnScope|Scope::DeclScope); - + ParseScope BodyScope(this, (parseMethod ? Scope::ObjCMethodScope : 0) | + Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope); + // Tell the actions module that we have entered a method or c-function definition // with the specified Declarator for the method/function. if (parseMethod) diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 353b0795f66..f5638773d90 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -302,6 +302,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { for (auto *D : DRD.get()) { TentativeParsingAction TPA(*this); ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope); // Parse <combiner> expression. Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D); @@ -337,6 +338,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { IsCorrect; if (Tok.isNot(tok::annot_pragma_openmp_end)) { ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope); // Parse expression. Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(), D); @@ -405,8 +407,9 @@ public: // If the Decl is on a function, add function parameters to the scope. HasFunScope = D->isFunctionOrFunctionTemplate(); - FnScope = new Parser::ParseScope(&P, Scope::FnScope | Scope::DeclScope, - HasFunScope); + FnScope = new Parser::ParseScope( + &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope, + HasFunScope); if (HasFunScope) Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D); } @@ -813,8 +816,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( SmallVector<OMPClause *, 5> Clauses; SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1> FirstClauses(OMPC_unknown + 1); - unsigned ScopeFlags = - Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope; + unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope; SourceLocation Loc = ConsumeAnnotationToken(), EndLoc; auto DKind = ParseOpenMPDirectiveKind(*this); OpenMPDirectiveKind CancelRegion = OMPD_unknown; diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index c5215ffceeb..198d5c6e9cb 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -533,7 +533,8 @@ StmtResult Parser::HandlePragmaCaptured() SourceLocation Loc = Tok.getLocation(); - ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope); + ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope); Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default, /*NumParams=*/1); diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index b1fbb20c721..65c3f21f2d9 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -453,9 +453,10 @@ StmtResult Parser::ParseSEHTryBlock() { if (Tok.isNot(tok::l_brace)) return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace); - StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false, - Scope::DeclScope | Scope::SEHTryScope)); - if(TryBlock.isInvalid()) + StmtResult TryBlock(ParseCompoundStatement( + /*isStmtExpr=*/false, + Scope::DeclScope | Scope::CompoundStmtScope | Scope::SEHTryScope)); + if (TryBlock.isInvalid()) return TryBlock; StmtResult Handler; @@ -840,7 +841,8 @@ StmtResult Parser::ParseDefaultStatement() { } StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) { - return ParseCompoundStatement(isStmtExpr, Scope::DeclScope); + return ParseCompoundStatement(isStmtExpr, + Scope::DeclScope | Scope::CompoundStmtScope); } /// ParseCompoundStatement - Parse a "{}" block. @@ -2085,9 +2087,10 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) { if (Tok.isNot(tok::l_brace)) return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace); - StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false, - Scope::DeclScope | Scope::TryScope | - (FnTry ? Scope::FnTryCatchScope : 0))); + StmtResult TryBlock(ParseCompoundStatement( + /*isStmtExpr=*/false, Scope::DeclScope | Scope::TryScope | + Scope::CompoundStmtScope | + (FnTry ? Scope::FnTryCatchScope : 0))); if (TryBlock.isInvalid()) return TryBlock; diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 944cd775d52..fc1722ea6cd 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -1380,7 +1380,8 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { // Parse the method body. Function body parsing code is similar enough // to be re-used for method bodies as well. - ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope); + ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope); // Recreate the containing function DeclContext. Sema::ContextRAII FunctionSavedContext(Actions, diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 4aa9a597192..51f4957a6e8 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1075,8 +1075,9 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, TemplateInfo.Kind == ParsedTemplateInfo::Template && Actions.canDelayFunctionBody(D)) { MultiTemplateParamsArg TemplateParameterLists(*TemplateInfo.TemplateParams); - - ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope); + + ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope); Scope *ParentScope = getCurScope()->getParent(); D.setFunctionDefinitionKind(FDK_Definition); @@ -1106,7 +1107,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) || Tok.is(tok::colon)) && Actions.CurContext->isTranslationUnit()) { - ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope); + ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope); Scope *ParentScope = getCurScope()->getParent(); D.setFunctionDefinitionKind(FDK_Definition); @@ -1124,7 +1126,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, } // Enter a scope for the function body. - ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope); + ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope); // Tell the actions module that we have entered a function definition with the // specified Declarator for the function. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 6bcb0231743..d19ace9c43b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12677,12 +12677,16 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, SourceLocation()); D.SetIdentifier(&II, Loc); - // Insert this function into translation-unit scope. + // Insert this function into the enclosing block scope. + while (S && !S->isCompoundStmtScope()) + S = S->getParent(); + if (S == nullptr) + S = TUScope; DeclContext *PrevDC = CurContext; CurContext = Context.getTranslationUnitDecl(); - FunctionDecl *FD = cast<FunctionDecl>(ActOnDeclarator(TUScope, D)); + FunctionDecl *FD = cast<FunctionDecl>(ActOnDeclarator(S, D)); FD->setImplicit(); CurContext = PrevDC; diff --git a/clang/test/Sema/implicit-decl-c90.c b/clang/test/Sema/implicit-decl-c90.c new file mode 100644 index 00000000000..38b01759a7d --- /dev/null +++ b/clang/test/Sema/implicit-decl-c90.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 %s -std=c90 -verify -fsyntax-only +void t0(int x) { + int (*p)(); + if(x > 0) + x = g() + 1; + p = g; + if(x < 0) { + extern void u(int (*)[h()]); + int (*q)() = h; + } + p = h; /* expected-error {{use of undeclared identifier 'h'}} */ +} + +void t1(int x) { + int (*p)(); + switch (x) { + g(); + case 0: + x = h() + 1; + break; + case 1: + p = g; + p = h; + break; + } + p = g; /* expected-error {{use of undeclared identifier 'g'}} */ + p = h; /* expected-error {{use of undeclared identifier 'h'}} */ +} + +int t2(int x) { + int y = ({ if (x > 0) x = g() + 1; 2*x; }); + int (*p)() = g; /* expected-error {{use of undeclared identifier 'g'}} */ + return y; +} + +int (*p)() = g; /* expected-error {{use of undeclared identifier 'g'}} */ +int (*q)() = h; /* expected-error {{use of undeclared identifier 'h'}} */ + +float g(); /* not expecting conflicting types diagnostics here */ diff --git a/clang/test/Sema/implicit-decl.c b/clang/test/Sema/implicit-decl.c index ffab9a6f913..0a892010783 100644 --- a/clang/test/Sema/implicit-decl.c +++ b/clang/test/Sema/implicit-decl.c @@ -9,8 +9,7 @@ void func() { int32_t *vector[16]; const char compDesc[16 + 1]; int32_t compCount = 0; - if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-note {{previous implicit declaration is here}} \ - expected-error {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}} + if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-error {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}} } printg("Hello, World!\n"); // expected-error{{implicit declaration of function 'printg' is invalid in C99}} \ @@ -18,7 +17,7 @@ void func() { __builtin_is_les(1, 3); // expected-error{{use of unknown builtin '__builtin_is_les'}} } -Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error{{conflicting types for '_CFCalendarDecomposeAbsoluteTimeV'}} +Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { return 0; } |