[cfe-commits] r45556 - in /cfe/trunk: Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp Sema/SemaStmt.cpp include/clang/Basic/DiagnosticKinds.def test/Sema/function-ptr.c

Chris Lattner sabre at nondot.org
Thu Jan 3 14:56:36 PST 2008


Author: lattner
Date: Thu Jan  3 16:56:36 2008
New Revision: 45556

URL: http://llvm.org/viewvc/llvm-project?rev=45556&view=rev
Log:
give better diagnostics for converting between function pointer and void*.

Added:
    cfe/trunk/test/Sema/function-ptr.c
Modified:
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/Sema/SemaStmt.cpp
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=45556&r1=45555&r2=45556&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Thu Jan  3 16:56:36 2008
@@ -612,6 +612,7 @@
     Incompatible,
     PointerFromInt, 
     IntFromPointer,
+    FunctionVoidPointer,
     IncompatiblePointer,
     CompatiblePointerDiscardsQualifiers
   };

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=45556&r1=45555&r2=45556&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Thu Jan  3 16:56:36 2008
@@ -394,6 +394,11 @@
          DeclType.getAsString(), rhsType.getAsString(), 
          Init->getSourceRange());
     break;
+  case FunctionVoidPointer:
+    Diag(Init->getLocStart(), diag::ext_typecheck_assign_pointer_void_func, 
+         DeclType.getAsString(), rhsType.getAsString(), 
+         Init->getSourceRange());
+    break;
   case IncompatiblePointer:
     Diag(Init->getLocStart(), diag::ext_typecheck_assign_incompatible_pointer,
          DeclType.getAsString(), rhsType.getAsString(), 

Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=45556&r1=45555&r2=45556&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Thu Jan  3 16:56:36 2008
@@ -644,6 +644,11 @@
              LHSType.getAsString(), RHSType.getAsString(),
              Fn->getSourceRange(), Arg->getSourceRange());
         break;
+      case FunctionVoidPointer:
+        Diag(Loc, diag::ext_typecheck_passing_pointer_void_func, 
+             LHSType.getAsString(), RHSType.getAsString(),
+             Fn->getSourceRange(), Arg->getSourceRange());
+        break;
       case IncompatiblePointer:
         Diag(Loc, diag::ext_typecheck_passing_incompatible_pointer, 
              RHSType.getAsString(), LHSType.getAsString(),
@@ -1075,17 +1080,29 @@
   // C99 6.5.16.1p1 (constraint 4): If one operand is a pointer to an object or 
   // incomplete type and the other is a pointer to a qualified or unqualified 
   // version of void...
-  if (lhptee.getUnqualifiedType()->isVoidType() &&
-      (rhptee->isObjectType() || rhptee->isIncompleteType()))
-    ;
-  else if (rhptee.getUnqualifiedType()->isVoidType() &&
-      (lhptee->isObjectType() || lhptee->isIncompleteType()))
-    ;
+  if (lhptee->isVoidType()) {
+    if (rhptee->isObjectType() || rhptee->isIncompleteType())
+      return r;
+    
+    // As an extension, we allow cast to/from void* to function pointer.
+    if (rhptee->isFunctionType())
+      return FunctionVoidPointer;
+  }
+  
+  if (rhptee->isVoidType()) {
+    if (lhptee->isObjectType() || lhptee->isIncompleteType())
+      return r;
+
+    // As an extension, we allow cast to/from void* to function pointer.
+    if (lhptee->isFunctionType())
+      return FunctionVoidPointer;
+  }
+  
   // C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or 
   // unqualified versions of compatible types, ...
-  else if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(), 
-                                       rhptee.getUnqualifiedType()))
-    r = IncompatiblePointer; // this "trumps" PointerAssignDiscardsQualifiers
+  if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(), 
+                                  rhptee.getUnqualifiedType()))
+    return IncompatiblePointer; // this "trumps" PointerAssignDiscardsQualifiers
   return r;
 }
 
@@ -1543,6 +1560,11 @@
          lhsType.getAsString(), rhsType.getAsString(),
          lex->getSourceRange(), rex->getSourceRange());
     break;
+  case FunctionVoidPointer:
+    Diag(loc, diag::ext_typecheck_assign_pointer_void_func, 
+         lhsType.getAsString(), rhsType.getAsString(),
+         lex->getSourceRange(), rex->getSourceRange());
+    break;
   case IncompatiblePointer:
     Diag(loc, diag::ext_typecheck_assign_incompatible_pointer,
          lhsType.getAsString(), rhsType.getAsString(),
@@ -2226,6 +2248,11 @@
            rhsType.getAsString(), lhsType.getAsString(),
            argExpr->getSourceRange());
       break;
+    case FunctionVoidPointer:
+      Diag(l, diag::ext_typecheck_sending_pointer_void_func, 
+           rhsType.getAsString(), lhsType.getAsString(),
+           argExpr->getSourceRange());
+      break;
     case CompatiblePointerDiscardsQualifiers:
       Diag(l, diag::ext_typecheck_passing_discards_qualifiers,
            rhsType.getAsString(), lhsType.getAsString(),

Modified: cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaStmt.cpp?rev=45556&r1=45555&r2=45556&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/Sema/SemaStmt.cpp Thu Jan  3 16:56:36 2008
@@ -663,6 +663,11 @@
          lhsType.getAsString(), rhsType.getAsString(),
          RetValExp->getSourceRange());
     break;
+  case FunctionVoidPointer:
+    Diag(ReturnLoc, diag::ext_typecheck_return_pointer_void_func, 
+         lhsType.getAsString(), rhsType.getAsString(),
+         RetValExp->getSourceRange());
+    break;
   case IncompatiblePointer:
     Diag(ReturnLoc, diag::ext_typecheck_return_incompatible_pointer,
          lhsType.getAsString(), rhsType.getAsString(),

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=45556&r1=45555&r2=45556&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Thu Jan  3 16:56:36 2008
@@ -767,6 +767,8 @@
      "incompatible pointer types assigning '%1' to '%0'")
 DIAG(ext_typecheck_assign_discards_qualifiers, WARNING,
      "assigning '%1' to '%0' discards qualifiers")
+DIAG(ext_typecheck_assign_pointer_void_func, EXTENSION,
+     "assigning '%1' to '%0' converts between void* and function pointer")
 DIAG(err_typecheck_array_not_modifiable_lvalue, ERROR,
      "array type '%0' is not assignable")
 DIAG(err_typecheck_non_object_not_modifiable_lvalue, ERROR,
@@ -791,6 +793,9 @@
      "incompatible pointer types passing '%0' to function expecting '%1'")
 DIAG(ext_typecheck_passing_pointer_int, WARNING,
      "incompatible types passing '%1' to function expecting '%0'")
+DIAG(ext_typecheck_passing_pointer_void_func, EXTENSION,
+     "passing '%1' to function expecting '%0' converts between void*"
+     " and function pointer")
 DIAG(ext_typecheck_passing_discards_qualifiers, WARNING,
      "passing '%0' to '%1' discards qualifiers")
 DIAG(err_typecheck_sending_incompatible, ERROR,
@@ -799,6 +804,9 @@
      "incompatible pointer types passing '%0' to method expecting '%1'")
 DIAG(ext_typecheck_sending_pointer_int, WARNING,
      "incompatible types passing '%1' to method expecting '%0'")
+DIAG(ext_typecheck_sending_pointer_void_func, EXTENSION,
+     "sending '%1' to method expecting '%0' converts between void*"
+     " and function pointer")
 DIAG(err_typecheck_cond_expect_scalar, ERROR,
      "used type '%0' where arithmetic or pointer type is required")
 DIAG(err_typecheck_expect_scalar_operand, ERROR,
@@ -909,6 +917,9 @@
      "incompatible type returning '%1', expected '%0'")
 DIAG(ext_typecheck_return_pointer_int, EXTENSION,
      "incompatible type returning '%1', expected '%0'")
+DIAG(ext_typecheck_return_pointer_void_func, EXTENSION,
+     "returning '%1' to from function expecting '%0' converts between void*"
+     " and function pointer")
 DIAG(ext_typecheck_return_incompatible_pointer, EXTENSION,
      "incompatible pointer type returning '%1', expected '%0'")
 DIAG(ext_typecheck_return_discards_qualifiers, EXTENSION,

Added: cfe/trunk/test/Sema/function-ptr.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/function-ptr.c?rev=45556&view=auto

==============================================================================
--- cfe/trunk/test/Sema/function-ptr.c (added)
+++ cfe/trunk/test/Sema/function-ptr.c Thu Jan  3 16:56:36 2008
@@ -0,0 +1,11 @@
+// RUN: clang %s -verify -pedantic
+typedef int unary_int_func(int arg);
+unary_int_func *func;
+
+unary_int_func *set_func(void *p) {
+ func = p; // expected-warning {{converts between void* and function pointer}}
+ p = func; // expected-warning {{converts between void* and function pointer}}
+
+ return p; // expected-warning {{converts between void* and function pointer}}
+}
+





More information about the cfe-commits mailing list