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...

llvm-svn: 294910
This commit is contained in:
Renato Golin 2017-02-12 19:08:02 +00:00
parent 4b08913de1
commit 510f37cc7d
5 changed files with 4 additions and 80 deletions

View File

@ -1888,13 +1888,6 @@ public:
/// immediately following this class.
template <typename T> const T *getAs() const;
/// Member-template getAsAdjusted<specific type>. Look through specific kinds
/// of sugar (parens, attributes, etc) for an instance of \<specific type>.
/// 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 \<specific type>
/// to another type that is still canonically a \<specific type>.
template <typename T> 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 <typename T> const T *Type::getAs() const {
return cast<T>(getUnqualifiedDesugaredType());
}
template <typename T> const T *Type::getAsAdjusted() const {
static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!");
// If this is directly a T type, return it.
if (const T *Ty = dyn_cast<T>(this))
return Ty;
// If the canonical form of this type isn't the right kind, reject it.
if (!isa<T>(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<AttributedType>(Ty))
Ty = A->getModifiedType().getTypePtr();
else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
Ty = E->desugar().getTypePtr();
else if (const auto *P = dyn_cast<ParenType>(Ty))
Ty = P->desugar().getTypePtr();
else if (const auto *A = dyn_cast<AdjustedType>(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<T>(Ty);
}
inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
// If this is directly an array type, return it.
if (const ArrayType *arr = dyn_cast<ArrayType>(this))

View File

@ -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 <typename T>
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 <typename T>
inline T TypeLoc::getAsAdjusted() const {
TypeLoc Cur = *this;
while (!T::isKind(Cur)) {
if (auto PTL = Cur.getAs<ParenTypeLoc>())
Cur = PTL.getInnerLoc();
else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
Cur = ATL.getModifiedLoc();
else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
Cur = ETL.getNamedTypeLoc();
else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
Cur = ATL.getOriginalLoc();
else
break;
}
return Cur.getAs<T>();
}
}
#endif

View File

@ -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<FunctionType>() && R->isFunctionProtoType());
(!isa<FunctionType>(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>();
FunctionTypeLoc FTL = TL.castAs<FunctionTypeLoc>();
Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 1;
}
}

View File

@ -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}}
{}

View File

@ -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;
{}