From: Steve Naroff Date: Mon, 27 Aug 2007 04:08:11 +0000 (+0000) Subject: Add Type::getAsBuiltinType() and Type::builtinTypesAreCompatible(). X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=77878cc5aa6ad01fc0c91bac1a61819dbf3bf691;p=clang 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). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41476 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/Type.cpp b/AST/Type.cpp index 65ba90a75d..f4c5aa748f 100644 --- a/AST/Type.cpp +++ b/AST/Type.cpp @@ -75,6 +75,18 @@ bool Type::isComplexType() const { return isa(CanonicalType); } +const BuiltinType *Type::getAsBuiltinType() const { + // If this is directly a builtin type, return it. + if (const BuiltinType *BTy = dyn_cast(this)) + return BTy; + + // If this is a typedef for a builtin type, strip the typedef off without + // losing all typedef information. + if (isa(CanonicalType)) + return cast(cast(this)->LookThroughTypedefs()); + return 0; +} + const FunctionType *Type::getAsFunctionType() const { // If this is directly a function type, return it. if (const FunctionType *FTy = dyn_cast(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"); } diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index cc9a64f726..9033ee917f 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -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()); diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index de5e48ee2c..9c72b050c5 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -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; diff --git a/test/Sema/compare.c b/test/Sema/compare.c index 0aeeb30d73..d4e29e8674 100644 --- a/test/Sema/compare.c +++ b/test/Sema/compare.c @@ -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; +} diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c index 323df34964..da3a21fcdd 100644 --- a/test/Sema/unused-expr.c +++ b/test/Sema/unused-expr.c @@ -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.