Skip to content

Commit

Permalink
Add an Extension warning for applying unary * to an operand of type '…
Browse files Browse the repository at this point in the history
…void*' in

C++. This seems like a pointless (and indeed harmful) restriction to me, so
I've suggested removing it to -core and disabled this diagnostic by default.

llvm-svn: 208254
  • Loading branch information
zygoloid committed May 7, 2014
1 parent c9124a5 commit 80877c2
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 5 deletions.
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -4685,6 +4685,9 @@ def err_typecheck_unary_expr : Error<
"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<
Expand Down
17 changes: 13 additions & 4 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9026,10 +9026,6 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,
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 =
Expand All @@ -9048,6 +9044,19 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,
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;

Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaCXX/decl-expr-ambiguity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void f() {
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'}}
Expand Down

0 comments on commit 80877c2

Please sign in to comment.