forked from OSchip/llvm-project
Add Type::getAsBuiltinType() and Type::builtinTypesAreCompatible().
Modified Type::typesAreCompatible() to use the above. This fixes the following bug submitted by Keith Bauer (thanks!). int equal(char *a, const char *b) { return a == b; } Also tweaked Sema::CheckCompareOperands() to ignore the qualifiers when comparing two pointer types (though it doesn't relate directly to this bug). llvm-svn: 41476
This commit is contained in:
parent
fc6ffa2513
commit
808eb8fe88
|
@ -75,6 +75,18 @@ bool Type::isComplexType() const {
|
|||
return isa<ComplexType>(CanonicalType);
|
||||
}
|
||||
|
||||
const BuiltinType *Type::getAsBuiltinType() const {
|
||||
// If this is directly a builtin type, return it.
|
||||
if (const BuiltinType *BTy = dyn_cast<BuiltinType>(this))
|
||||
return BTy;
|
||||
|
||||
// If this is a typedef for a builtin type, strip the typedef off without
|
||||
// losing all typedef information.
|
||||
if (isa<BuiltinType>(CanonicalType))
|
||||
return cast<BuiltinType>(cast<TypedefType>(this)->LookThroughTypedefs());
|
||||
return 0;
|
||||
}
|
||||
|
||||
const FunctionType *Type::getAsFunctionType() const {
|
||||
// If this is directly a function type, return it.
|
||||
if (const FunctionType *FTy = dyn_cast<FunctionType>(this))
|
||||
|
@ -204,6 +216,12 @@ const OCUVectorType *Type::getAsOCUVectorType() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool Type::builtinTypesAreCompatible(QualType lhs, QualType rhs) {
|
||||
const BuiltinType *lBuiltin = lhs->getAsBuiltinType();
|
||||
const BuiltinType *rBuiltin = rhs->getAsBuiltinType();
|
||||
|
||||
return lBuiltin->getKind() == rBuiltin->getKind();
|
||||
}
|
||||
|
||||
// C99 6.2.7p1: If both are complete types, then the following additional
|
||||
// requirements apply...FIXME (handle compatibility across source files).
|
||||
|
@ -334,7 +352,7 @@ bool Type::typesAreCompatible(QualType lhs, QualType rhs) {
|
|||
case Type::Tagged: // handle structures, unions
|
||||
return tagTypesAreCompatible(lcanon, rcanon);
|
||||
case Type::Builtin:
|
||||
return false;
|
||||
return builtinTypesAreCompatible(lcanon, rcanon);
|
||||
default:
|
||||
assert(0 && "unexpected type");
|
||||
}
|
||||
|
|
|
@ -1109,9 +1109,10 @@ inline QualType Sema::CheckCompareOperands( // C99 6.5.8
|
|||
// All of the following pointer related warnings are GCC extensions, except
|
||||
// when handling null pointer constants. One day, we can consider making them
|
||||
// errors (when -pedantic-errors is enabled).
|
||||
if (lType->isPointerType() && rType->isPointerType()) {
|
||||
if (lType->isPointerType() && rType->isPointerType()) { // C99 6.5.8p2
|
||||
if (!LHSIsNull && !RHSIsNull &&
|
||||
!Type::pointerTypesAreCompatible(lType, rType)) {
|
||||
!Type::pointerTypesAreCompatible(lType.getUnqualifiedType(),
|
||||
rType.getUnqualifiedType())) {
|
||||
Diag(loc, diag::ext_typecheck_comparison_of_distinct_pointers,
|
||||
lType.getAsString(), rType.getAsString(),
|
||||
lex->getSourceRange(), rex->getSourceRange());
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace clang {
|
|||
class TagType;
|
||||
class FunctionType;
|
||||
class OCUVectorType;
|
||||
class BuiltinType;
|
||||
|
||||
/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
|
||||
/// their own: instead each reference to a type stores the qualifiers. This
|
||||
|
@ -262,6 +263,7 @@ public:
|
|||
// Type Checking Functions: Check to see if this type is structurally the
|
||||
// specified type, ignoring typedefs, and return a pointer to the best type
|
||||
// we can.
|
||||
const BuiltinType *getAsBuiltinType() const;
|
||||
const FunctionType *getAsFunctionType() const;
|
||||
const PointerType *getAsPointerType() const;
|
||||
const ReferenceType *getAsReferenceType() const;
|
||||
|
@ -297,6 +299,7 @@ public:
|
|||
static bool referenceTypesAreCompatible(QualType, QualType); // C++ 5.17p6
|
||||
static bool functionTypesAreCompatible(QualType, QualType); // C99 6.7.5.3p15
|
||||
static bool arrayTypesAreCompatible(QualType, QualType); // C99 6.7.5.2p6
|
||||
static bool builtinTypesAreCompatible(QualType, QualType);
|
||||
private:
|
||||
QualType getCanonicalTypeInternal() const { return CanonicalType; }
|
||||
friend class QualType;
|
||||
|
|
|
@ -6,3 +6,7 @@ int test(char *C) { // nothing here should warn.
|
|||
return C != 0;
|
||||
}
|
||||
|
||||
int equal(char *a, const char *b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@ int foo(int X, int Y);
|
|||
void bar(volatile int *VP, int *P, int A,
|
||||
_Complex double C, volatile _Complex double VC) {
|
||||
|
||||
VP == P; // expected-warning {{expression result unused}} \
|
||||
expected-warning {{comparison}}
|
||||
VP == P; // expected-warning {{expression result unused}}
|
||||
(void)A;
|
||||
(void)foo(1,2); // no warning.
|
||||
|
||||
|
|
Loading…
Reference in New Issue