]> granicus.if.org Git - clang/commitdiff
Tighten up ASTContext::typesAreCompatible()...it needs to make sure the qualifiers...
authorSteve Naroff <snaroff@apple.com>
Tue, 29 Jan 2008 18:58:14 +0000 (18:58 +0000)
committerSteve Naroff <snaroff@apple.com>
Tue, 29 Jan 2008 18:58:14 +0000 (18:58 +0000)
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

AST/ASTContext.cpp
Sema/SemaExpr.cpp
test/Sema/function.c

index c86cf6797cf8ee7c09d85f81da40e7066b8aebe2..8d620d9d62e414554317af4476abc627b59abaa8 100644 (file)
@@ -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();
 
index ab63dc6993d49c06fbec16f5f847e7438003ddc4..a1cdb225662aaa4864b16fc0b25b0696b0e499a0 100644 (file)
@@ -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());
index 34e523586c5316b32f1affc32df951b34740920e..17cc86ef13879ebb4cce5fe23c1e796eba910f30 100644 (file)
@@ -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)()) {
 }