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:
Steve Naroff 2007-08-27 04:08:11 +00:00
parent fc6ffa2513
commit 808eb8fe88
5 changed files with 30 additions and 5 deletions

View File

@ -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");
}

View File

@ -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());

View File

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

View File

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

View File

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