give better diagnostics for converting between function pointer and void*.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45556 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index 1ec60d9..68c301a 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -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(),