chill updated this revision to Diff 106056. chill added a comment. Herald added a subscriber: eraman.
Set the compound statement flag on all compound statement scopes (previous version used to set the flag on just enough scopes as to be sufficient for the purpose of inserting C90 implicit function declarations in said scopes). https://reviews.llvm.org/D33676 Files: include/clang/Sema/Scope.h lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseObjc.cpp lib/Parse/ParseOpenMP.cpp lib/Parse/ParsePragma.cpp lib/Parse/ParseStmt.cpp lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp lib/Sema/SemaDecl.cpp test/Sema/implicit-decl-c90.c test/Sema/implicit-decl.c
Index: test/Sema/implicit-decl.c =================================================================== --- test/Sema/implicit-decl.c +++ test/Sema/implicit-decl.c @@ -9,16 +9,15 @@ 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}} \ // expected-note{{did you mean 'printf'?}} __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; } Index: test/Sema/implicit-decl-c90.c =================================================================== --- /dev/null +++ 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 */ Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -12662,12 +12662,16 @@ 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; Index: lib/Parse/Parser.cpp =================================================================== --- lib/Parse/Parser.cpp +++ lib/Parse/Parser.cpp @@ -1076,7 +1076,8 @@ 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 @@ (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 @@ } // 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. Index: lib/Parse/ParseTemplate.cpp =================================================================== --- lib/Parse/ParseTemplate.cpp +++ lib/Parse/ParseTemplate.cpp @@ -1380,7 +1380,8 @@ // 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, Index: lib/Parse/ParseStmt.cpp =================================================================== --- lib/Parse/ParseStmt.cpp +++ lib/Parse/ParseStmt.cpp @@ -454,7 +454,8 @@ return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace); StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false, - Scope::DeclScope | Scope::SEHTryScope)); + Scope::DeclScope | Scope::CompoundStmtScope | + Scope::SEHTryScope)); if(TryBlock.isInvalid()) return TryBlock; @@ -840,7 +841,8 @@ } StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) { - return ParseCompoundStatement(isStmtExpr, Scope::DeclScope); + return ParseCompoundStatement(isStmtExpr, + Scope::DeclScope | Scope::CompoundStmtScope); } /// ParseCompoundStatement - Parse a "{}" block. @@ -2087,7 +2089,8 @@ StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false, Scope::DeclScope | Scope::TryScope | - (FnTry ? Scope::FnTryCatchScope : 0))); + Scope::CompoundStmtScope | + (FnTry ? Scope::FnTryCatchScope : 0))); if (TryBlock.isInvalid()) return TryBlock; Index: lib/Parse/ParsePragma.cpp =================================================================== --- lib/Parse/ParsePragma.cpp +++ lib/Parse/ParsePragma.cpp @@ -528,7 +528,8 @@ 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); Index: lib/Parse/ParseOpenMP.cpp =================================================================== --- lib/Parse/ParseOpenMP.cpp +++ lib/Parse/ParseOpenMP.cpp @@ -302,7 +302,8 @@ for (auto *D : DRD.get()) { TentativeParsingAction TPA(*this); ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope | - Scope::OpenMPDirectiveScope); + Scope::CompoundStmtScope | + Scope::OpenMPDirectiveScope); // Parse <combiner> expression. Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D); ExprResult CombinerResult = @@ -337,7 +338,8 @@ IsCorrect; if (Tok.isNot(tok::annot_pragma_openmp_end)) { ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope | - Scope::OpenMPDirectiveScope); + Scope::CompoundStmtScope | + Scope::OpenMPDirectiveScope); // Parse expression. Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(), D); InitializerResult = Actions.ActOnFinishFullExpr( @@ -405,7 +407,8 @@ // 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, + FnScope = new Parser::ParseScope(&P, Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope, HasFunScope); if (HasFunScope) Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D); @@ -814,7 +817,8 @@ SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1> FirstClauses(OMPC_unknown + 1); unsigned ScopeFlags = - Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope; + Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope | + Scope::OpenMPDirectiveScope; SourceLocation Loc = ConsumeAnnotationToken(), EndLoc; auto DKind = ParseOpenMPDirectiveKind(*this); OpenMPDirectiveKind CancelRegion = OMPD_unknown; Index: lib/Parse/ParseObjc.cpp =================================================================== --- lib/Parse/ParseObjc.cpp +++ lib/Parse/ParseObjc.cpp @@ -2474,7 +2474,7 @@ 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(); @@ -2510,7 +2510,7 @@ } StmtVector CatchStmts; StmtResult FinallyStmt; - ParseScope TryScope(this, Scope::DeclScope); + ParseScope TryScope(this, Scope::DeclScope|Scope::CompoundStmtScope); StmtResult TryBody(ParseCompoundStatementBody()); TryScope.Exit(); if (TryBody.isInvalid()) @@ -2531,7 +2531,8 @@ 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); @@ -2575,7 +2576,7 @@ } 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)) @@ -2612,7 +2613,7 @@ } // 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()); @@ -3647,9 +3648,9 @@ "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); + (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. Index: lib/Parse/ParseExprCXX.cpp =================================================================== --- lib/Parse/ParseExprCXX.cpp +++ lib/Parse/ParseExprCXX.cpp @@ -1281,7 +1281,8 @@ // 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()); Index: lib/Parse/ParseExpr.cpp =================================================================== --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -2881,6 +2881,7 @@ // allows determining whether a variable reference inside the block is // within or outside of the block. ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope | + Scope::CompoundStmtScope | Scope::DeclScope); // Inform sema that we are starting a block. Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -1388,7 +1388,9 @@ // 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); Index: lib/Parse/ParseCXXInlineMethods.cpp =================================================================== --- lib/Parse/ParseCXXInlineMethods.cpp +++ lib/Parse/ParseCXXInlineMethods.cpp @@ -518,7 +518,8 @@ // 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)) { Index: include/clang/Sema/Scope.h =================================================================== --- include/clang/Sema/Scope.h +++ include/clang/Sema/Scope.h @@ -124,6 +124,9 @@ /// 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,9 @@ /// \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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits