From: Renato Golin Date: Sun, 12 Feb 2017 19:08:02 +0000 (+0000) Subject: Revert "Attributes on K&R C functions should not cause incompatible..." X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=17ad1c0c58545231709072bc0ff038811da9958f;p=clang Revert "Attributes on K&R C functions should not cause incompatible..." ...function type with a redeclaration having the same attribute. Fixing this introduced a secondary problem where we were assuming that K&R functions could not be attributed types when reporting old-style function definitions that are not preceded by a prototype." Also Revert "Hopefully fixes a compile error introduced by r294861." This reverts commit r294862, r294861, as they bork the ARM builds and haven't fix it back. Also, please, short commit titles, long commit decsriptions... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@294910 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 0db0905cba..0a50b618c9 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1888,13 +1888,6 @@ public: /// immediately following this class. template const T *getAs() const; - /// Member-template getAsAdjusted. Look through specific kinds - /// of sugar (parens, attributes, etc) for an instance of \. - /// This is used when you need to walk over sugar nodes that represent some - /// kind of type adjustment from a type that was written as a \ - /// to another type that is still canonically a \. - template const T *getAsAdjusted() const; - /// A variant of getAs<> for array types which silently discards /// qualifiers from the outermost type. const ArrayType *getAsArrayTypeUnsafe() const; @@ -6015,38 +6008,6 @@ template const T *Type::getAs() const { return cast(getUnqualifiedDesugaredType()); } -template const T *Type::getAsAdjusted() const { - static_assert(!TypeIsArrayType::value, "ArrayType cannot be used with getAsAdjusted!"); - - // If this is directly a T type, return it. - if (const T *Ty = dyn_cast(this)) - return Ty; - - // If the canonical form of this type isn't the right kind, reject it. - if (!isa(CanonicalType)) - return nullptr; - - // Strip off type adjustments that do not modify the underlying nature of the - // type. - const Type *Ty = this; - while (Ty) { - if (const auto *A = dyn_cast(Ty)) - Ty = A->getModifiedType().getTypePtr(); - else if (const auto *E = dyn_cast(Ty)) - Ty = E->desugar().getTypePtr(); - else if (const auto *P = dyn_cast(Ty)) - Ty = P->desugar().getTypePtr(); - else if (const auto *A = dyn_cast(Ty)) - Ty = A->desugar().getTypePtr(); - else - break; - } - - // Just because the canonical type is correct does not mean we can use cast<>, - // since we may not have stripped off all the sugar down to the base type. - return dyn_cast(Ty); -} - inline const ArrayType *Type::getAsArrayTypeUnsafe() const { // If this is directly an array type, return it. if (const ArrayType *arr = dyn_cast(this)) diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 525f848a9f..a10b9792d9 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -70,13 +70,6 @@ public: return t; } - /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if - /// this TypeLock is not of the desired type. It will consider type - /// adjustments from a type that wad written as a T to another type that is - /// still canonically a T (ignores parens, attributes, elaborated types, etc). - template - T getAsAdjusted() const; - /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, /// except it also defines a Qualified enum that corresponds to the /// QualifiedLoc class. @@ -2195,24 +2188,6 @@ public: QualType getInnerType() const { return this->getTypePtr()->getElementType(); } }; - -template -inline T TypeLoc::getAsAdjusted() const { - TypeLoc Cur = *this; - while (!T::isKind(Cur)) { - if (auto PTL = Cur.getAs()) - Cur = PTL.getInnerLoc(); - else if (auto ATL = Cur.getAs()) - Cur = ATL.getModifiedLoc(); - else if (auto ETL = Cur.getAs()) - Cur = ETL.getNamedTypeLoc(); - else if (auto ATL = Cur.getAs()) - Cur = ATL.getOriginalLoc(); - else - break; - } - return Cur.getAs(); -} } #endif diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index bc4611cb06..5f98d4505f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -7564,12 +7564,11 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, // Determine whether the function was written with a // prototype. This true when: // - there is a prototype in the declarator, or - // - the type R of the function is some kind of typedef or other non- - // attributed reference to a type name (which eventually refers to a - // function type). + // - the type R of the function is some kind of typedef or other reference + // to a type name (which eventually refers to a function type). bool HasPrototype = (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) || - (!R->getAsAdjusted() && R->isFunctionProtoType()); + (!isa(R.getTypePtr()) && R->isFunctionProtoType()); NewFD = FunctionDecl::Create(SemaRef.Context, DC, D.getLocStart(), NameInfo, R, @@ -12105,7 +12104,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, !LangOpts.CPlusPlus) { TypeSourceInfo *TI = FD->getTypeSourceInfo(); TypeLoc TL = TI->getTypeLoc(); - FunctionTypeLoc FTL = TL.getAsAdjusted(); + FunctionTypeLoc FTL = TL.castAs(); Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 1; } } diff --git a/test/Sema/knr-def-call.c b/test/Sema/knr-def-call.c index ab7e3c9b17..80ad0d820b 100644 --- a/test/Sema/knr-def-call.c +++ b/test/Sema/knr-def-call.c @@ -39,9 +39,3 @@ void use_proto() { proto(42.1); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 42.1 to 42}} (&proto)(42.1); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 42.1 to 42}} } - -// PR31020 -void func(short d) __attribute__((cdecl)); // expected-note{{previous declaration is here}} -void __attribute__((cdecl)) func(d) - short d; // expected-warning{{promoted type 'int' of K&R function parameter is not compatible with the parameter type 'short' declared in a previous prototype}} -{} diff --git a/test/Sema/warn-strict-prototypes.c b/test/Sema/warn-strict-prototypes.c index b70f38f9e0..496579c1f6 100644 --- a/test/Sema/warn-strict-prototypes.c +++ b/test/Sema/warn-strict-prototypes.c @@ -60,8 +60,3 @@ void foo10(p, p2) void *p; {} // expected-warning {{old-style function definitio // K&R function definition with previous prototype declared is not diagnosed. void foo11(int p, int p2); void foo11(p, p2) int p; int p2; {} - -// PR31020 -void __attribute__((cdecl)) foo12(d) // expected-warning {{this old-style function definition is not preceded by a prototype}} - short d; -{}