From: Steve Naroff Date: Tue, 29 Jan 2008 18:58:14 +0000 (+0000) Subject: Tighten up ASTContext::typesAreCompatible()...it needs to make sure the qualifiers... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2565eeff7b0d2310fb2924ce96a54302b0dfa5af;p=clang Tighten up ASTContext::typesAreCompatible()...it needs to make sure the qualifiers match. The comment and C99 citation for this routine were correct...the code needed to conform to the comment/spec. This fixes the test added below. Tightening up this routine forced tweaks to Sema::CheckSubtractionOperands() and Sema::CheckCompareOperands(). For example, they both need to operate on the unqualified pointee... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46522 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index c86cf6797c..8d620d9d62 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -1617,6 +1617,9 @@ bool ASTContext::arrayTypesAreCompatible(QualType lhs, QualType rhs) { /// C99 6.2.7p1: Two types have compatible types if their types are the /// same. See 6.7.[2,3,5] for additional rules. bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) { + if (lhs.getQualifiers() != rhs.getQualifiers()) + return false; + QualType lcanon = lhs.getCanonicalType(); QualType rcanon = rhs.getCanonicalType(); diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index ab63dc6993..a1cdb22566 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -1337,10 +1337,12 @@ inline QualType Sema::CheckSubtractionOperands( // C99 6.5.6 // Either ptr - int or ptr - ptr. if (const PointerType *LHSPTy = lex->getType()->getAsPointerType()) { + QualType lpointee = LHSPTy->getPointeeType(); + // The LHS must be an object type, not incomplete, function, etc. - if (!LHSPTy->getPointeeType()->isObjectType()) { + if (!lpointee->isObjectType()) { // Handle the GNU void* extension. - if (LHSPTy->getPointeeType()->isVoidType()) { + if (lpointee->isVoidType()) { Diag(loc, diag::ext_gnu_void_ptr, lex->getSourceRange(), rex->getSourceRange()); } else { @@ -1356,11 +1358,13 @@ inline QualType Sema::CheckSubtractionOperands( // C99 6.5.6 // Handle pointer-pointer subtractions. if (const PointerType *RHSPTy = rex->getType()->getAsPointerType()) { + QualType rpointee = RHSPTy->getPointeeType(); + // RHS must be an object type, unless void (GNU). - if (!RHSPTy->getPointeeType()->isObjectType()) { + if (!rpointee->isObjectType()) { // Handle the GNU void* extension. - if (RHSPTy->getPointeeType()->isVoidType()) { - if (!LHSPTy->getPointeeType()->isVoidType()) + if (rpointee->isVoidType()) { + if (!lpointee->isVoidType()) Diag(loc, diag::ext_gnu_void_ptr, lex->getSourceRange(), rex->getSourceRange()); } else { @@ -1371,8 +1375,8 @@ inline QualType Sema::CheckSubtractionOperands( // C99 6.5.6 } // Pointee types must be compatible. - if (!Context.typesAreCompatible(LHSPTy->getPointeeType(), - RHSPTy->getPointeeType())) { + if (!Context.typesAreCompatible(lpointee.getUnqualifiedType(), + rpointee.getUnqualifiedType())) { Diag(loc, diag::err_typecheck_sub_ptr_compatible, lex->getType().getAsString(), rex->getType().getAsString(), lex->getSourceRange(), rex->getSourceRange()); @@ -1446,12 +1450,13 @@ inline QualType Sema::CheckCompareOperands( // C99 6.5.8 // when handling null pointer constants. One day, we can consider making them // errors (when -pedantic-errors is enabled). if (lType->isPointerType() && rType->isPointerType()) { // C99 6.5.8p2 - + QualType lpointee = lType->getAsPointerType()->getPointeeType(); + QualType rpointee = rType->getAsPointerType()->getPointeeType(); + if (!LHSIsNull && !RHSIsNull && // C99 6.5.9p2 - !lType->getAsPointerType()->getPointeeType()->isVoidType() && - !rType->getAsPointerType()->getPointeeType()->isVoidType() && - !Context.pointerTypesAreCompatible(lType.getUnqualifiedType(), - rType.getUnqualifiedType())) { + !lpointee->isVoidType() && !lpointee->isVoidType() && + !Context.typesAreCompatible(lpointee.getUnqualifiedType(), + rpointee.getUnqualifiedType())) { Diag(loc, diag::ext_typecheck_comparison_of_distinct_pointers, lType.getAsString(), rType.getAsString(), lex->getSourceRange(), rex->getSourceRange()); diff --git a/test/Sema/function.c b/test/Sema/function.c index 34e523586c..17cc86ef13 100644 --- a/test/Sema/function.c +++ b/test/Sema/function.c @@ -1,4 +1,4 @@ -// RUN: clang %s -fsyntax-only +// RUN: clang %s -fsyntax-only -verify // PR1892 void f(double a[restrict][5]); // should promote to restrict ptr. void f(double (* restrict a)[5]); @@ -6,6 +6,9 @@ void f(double (* restrict a)[5]); int foo (__const char *__path); int foo(__const char *__restrict __file); +void func(const char*); //expected-error{{previous declaration is here}} +void func(char*); //expected-error{{conflicting types for 'func'}} + void g(int (*)(const void **, const void **)); void g(int (*compar)()) { }