diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-22 05:27:59 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-22 05:27:59 +0000 |
commit | 3f84ad22acc25353a47ee88f55ab05dffef5d9a9 (patch) | |
tree | 0866ac903b6015d0e76e86f8ddd1857c593defa4 | |
parent | 1e27472262b50097e0292b4352810e168df2eaa7 (diff) |
change implicit int warnings to point to the identifier, not the
start of the declspec. The fixit still goes there, and we underline
the declspec. This helps when the start of the declspec came from a
macro that expanded from a system header. For example, we now produce:
t.c:2:8: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
static x;
~~~~~~ ^
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69777 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 50 | ||||
-rw-r--r-- | test/Sema/block-literal.c | 2 | ||||
-rw-r--r-- | test/Sema/implicit-int.c | 3 |
4 files changed, 36 insertions, 21 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index f3c337c148..e8c69c2f5f 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -371,7 +371,7 @@ public: // Type Analysis / Processing: SemaType.cpp. // QualType adjustParameterType(QualType T); - QualType ConvertDeclSpecToType(const DeclSpec &DS); + QualType ConvertDeclSpecToType(const DeclSpec &DS, SourceLocation DeclLoc); void ProcessTypeAttributeList(QualType &Result, const AttributeList *AL); QualType BuildPointerType(QualType T, unsigned Quals, SourceLocation Loc, DeclarationName Entity); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index b8969a2202..50f5071306 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -46,9 +46,11 @@ QualType Sema::adjustParameterType(QualType T) { /// \brief Convert the specified declspec to the appropriate type /// object. /// \param DS the declaration specifiers +/// \param DeclLoc The location of the declarator identifier or invalid if none. /// \returns The type described by the declaration specifiers, or NULL /// if there was an error. -QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) { +QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, + SourceLocation DeclLoc) { // FIXME: Should move the logic from DeclSpec::Finish to here for validity // checking. QualType Result; @@ -101,20 +103,29 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) { if (getLangOptions().ImplicitInt) { // In C89 mode, we only warn if there is a completely missing declspec // when one is not allowed. - if (DS.isEmpty()) - Diag(DS.getSourceRange().getBegin(), diag::warn_missing_declspec) + if (DS.isEmpty()) { + if (DeclLoc.isInvalid()) + DeclLoc = DS.getSourceRange().getBegin(); + Diag(DeclLoc, diag::warn_missing_declspec) + << DS.getSourceRange() << CodeModificationHint::CreateInsertion(DS.getSourceRange().getBegin(), "int"); + } } else if (!DS.hasTypeSpecifier()) { // C99 and C++ require a type specifier. For example, C99 6.7.2p2 says: // "At least one type specifier shall be given in the declaration // specifiers in each declaration, and in the specifier-qualifier list in // each struct declaration and type name." // FIXME: Does Microsoft really have the implicit int extension in C++? - unsigned DK = getLangOptions().CPlusPlus && !getLangOptions().Microsoft? - diag::err_missing_type_specifier - : diag::warn_missing_type_specifier; - Diag(DS.getSourceRange().getBegin(), DK); + if (DeclLoc.isInvalid()) + DeclLoc = DS.getSourceRange().getBegin(); + + if (getLangOptions().CPlusPlus && !getLangOptions().Microsoft) + Diag(DeclLoc, diag::err_missing_type_specifier) + << DS.getSourceRange(); + else + Diag(DeclLoc, diag::warn_missing_type_specifier) + << DS.getSourceRange(); // FIXME: If we could guarantee that the result would be // well-formed, it would be useful to have a code insertion hint @@ -183,13 +194,18 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) { // id<protocol-list> Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers()); - else if (Result == Context.getObjCClassType()) + else if (Result == Context.getObjCClassType()) { + if (DeclLoc.isInvalid()) + DeclLoc = DS.getSourceRange().getBegin(); // Class<protocol-list> - Diag(DS.getSourceRange().getBegin(), - diag::err_qualified_class_unsupported) << DS.getSourceRange(); - else - Diag(DS.getSourceRange().getBegin(), - diag::err_invalid_protocol_qualifiers) << DS.getSourceRange(); + Diag(DeclLoc, diag::err_qualified_class_unsupported) + << DS.getSourceRange(); + } else { + if (DeclLoc.isInvalid()) + DeclLoc = DS.getSourceRange().getBegin(); + Diag(DeclLoc, diag::err_invalid_protocol_qualifiers) + << DS.getSourceRange(); + } } // TypeQuals handled by caller. break; @@ -592,13 +608,13 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) { case Declarator::DK_Abstract: case Declarator::DK_Normal: case Declarator::DK_Operator: { - const DeclSpec& DS = D.getDeclSpec(); - if (OmittedReturnType) + const DeclSpec &DS = D.getDeclSpec(); + if (OmittedReturnType) { // We default to a dependent type initially. Can be modified by // the first return statement. T = Context.DependentTy; - else { - T = ConvertDeclSpecToType(DS); + } else { + T = ConvertDeclSpecToType(DS, D.getIdentifierLoc()); if (T.isNull()) return T; } diff --git a/test/Sema/block-literal.c b/test/Sema/block-literal.c index c6e3931aa8..19d476fc29 100644 --- a/test/Sema/block-literal.c +++ b/test/Sema/block-literal.c @@ -40,7 +40,7 @@ void test2() { foo: takeclosure(^{ x = 4; }); // expected-error {{variable is not assignable (missing __block type specifier)}} - __block y = 7; + __block y = 7; // expected-warning {{type specifier missing, defaults to 'int'}} takeclosure(^{ y = 8; }); } diff --git a/test/Sema/implicit-int.c b/test/Sema/implicit-int.c index 90fe607e12..04b27a8f0e 100644 --- a/test/Sema/implicit-int.c +++ b/test/Sema/implicit-int.c @@ -23,8 +23,7 @@ h19_insline(n) // expected-warning {{parameter 'n' was not declared, defaulting } struct foo { - __extension__ __attribute__((packed)) // expected-warning {{type specifier missing, defaults to 'int'}} - x : 4; + __extension__ __attribute__((packed)) x : 4; // expected-warning {{type specifier missing, defaults to 'int'}} }; |