"invalid argument type %0 to unary expression">;
def err_typecheck_indirection_requires_pointer : Error<
"indirection requires pointer operand (%0 invalid)">;
+def ext_typecheck_indirection_through_void_pointer : Extension<
+ "ISO C++ does not allow indirection on operand of type %0">,
+ InGroup<DiagGroup<"void-ptr-dereference">>;
def warn_indirection_through_null : Warning<
"indirection of non-volatile null pointer will be deleted, not trap">, InGroup<NullDereference>;
def note_indirection_through_null : Note<
Op->getSourceRange());
}
- // Note that per both C89 and C99, indirection is always legal, even if OpTy
- // is an incomplete type or void. It would be possible to warn about
- // dereferencing a void pointer, but it's completely well-defined, and such a
- // warning is unlikely to catch any mistakes.
if (const PointerType *PT = OpTy->getAs<PointerType>())
Result = PT->getPointeeType();
else if (const ObjCObjectPointerType *OPT =
return QualType();
}
+ // Note that per both C89 and C99, indirection is always legal, even if Result
+ // is an incomplete type or void. It would be possible to warn about
+ // dereferencing a void pointer, but it's completely well-defined, and such a
+ // warning is unlikely to catch any mistakes. In C++, indirection is not valid
+ // for pointers to 'void' but is fine for any other pointer type:
+ //
+ // C++ [expr.unary.op]p1:
+ // [...] the expression to which [the unary * operator] is applied shall
+ // be a pointer to an object type, or a pointer to a function type
+ if (S.getLangOpts().CPlusPlus && Result->isVoidType())
+ S.Diag(OpLoc, diag::ext_typecheck_indirection_through_void_pointer)
+ << OpTy << Op->getSourceRange();
+
// Dereferences are usually l-values...
VK = VK_LValue;
extern T f3();
__typeof(*T()) f4(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
typedef void *V;
- __typeof(*V()) f5();
+ __typeof(*V()) f5(); // expected-error {{ISO C++ does not allow indirection on operand of type 'V' (aka 'void *')}}
T multi1,
multi2(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
T(d)[5]; // expected-error {{redefinition of 'd'}}