From 359a15d245c470904bc39940f45933330bb314b5 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 7 May 2014 21:53:27 +0000 Subject: [PATCH] Add an Extension warning for applying unary * to an operand of type '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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208254 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 3 +++ lib/Sema/SemaExpr.cpp | 17 +++++++++++++---- test/SemaCXX/decl-expr-ambiguity.cpp | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index c39accece2..27ca1c9346 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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>; def warn_indirection_through_null : Warning< "indirection of non-volatile null pointer will be deleted, not trap">, InGroup; def note_indirection_through_null : Note< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index e4b42402dc..979c28cbd8 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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()) Result = PT->getPointeeType(); else if (const ObjCObjectPointerType *OPT = @@ -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; diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp index 8164b2bc91..6abfb2f328 100644 --- a/test/SemaCXX/decl-expr-ambiguity.cpp +++ b/test/SemaCXX/decl-expr-ambiguity.cpp @@ -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'}} -- 2.40.0