diff options
author | John McCall <rjmccall@apple.com> | 2010-04-06 22:24:14 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-04-06 22:24:14 +0000 |
commit | 209acbd6d0c1b4444eb8c1682717753e1cbe38de (patch) | |
tree | 05a24c0410ee04ea08f192f0920470d3d8c6886b | |
parent | 68b9a599dda7c422a417dfdc330adb5a880eb0e5 (diff) |
Devote a special diagnostic to the typo
(void*) someFunction(5, 10, 15, 20);
where the cast is presumably meant to be to 'void'.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100574 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 17 | ||||
-rw-r--r-- | test/Sema/unused-expr.c | 6 |
3 files changed, 26 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b66d6cc6e5..ebd3a4e252 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2359,6 +2359,9 @@ def ext_typecheck_expression_not_constant_but_accepted : Extension< InGroup<GNU>; def warn_unused_expr : Warning<"expression result unused">, InGroup<UnusedValue>; +def warn_unused_voidptr : Warning< + "expression result unused; should this cast be to 'void'?">, + InGroup<UnusedValue>; def warn_unused_property_expr : Warning< "property access result unused - getters should not have side effects">, InGroup<UnusedValue>; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 791de8c2b9..0c55cf5c5c 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -20,6 +20,7 @@ #include "clang/AST/ExprObjC.h" #include "clang/AST/StmtObjC.h" #include "clang/AST/StmtCXX.h" +#include "clang/AST/TypeLoc.h" #include "clang/Lex/Preprocessor.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/STLExtras.h" @@ -126,6 +127,22 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { return; } } + + // Diagnose "(void*) blah" as a typo for "(void) blah". + else if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(E)) { + TypeSourceInfo *TI = CE->getTypeInfoAsWritten(); + QualType T = TI->getType(); + + // We really do want to use the non-canonical type here. + if (T == Context.VoidPtrTy) { + PointerTypeLoc TL = cast<PointerTypeLoc>(TI->getTypeLoc()); + + Diag(Loc, diag::warn_unused_voidptr) + << FixItHint::CreateRemoval(TL.getStarLoc()); + return; + } + } + Diag(Loc, DiagID) << R1 << R2; } diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c index 4c6c47b345..4ae0d4b465 100644 --- a/test/Sema/unused-expr.c +++ b/test/Sema/unused-expr.c @@ -104,3 +104,9 @@ void t8() { } void t9() __attribute__((warn_unused_result)); // expected-warning {{attribute 'warn_unused_result' cannot be applied to functions without return value}} + +// rdar://7410924 +void *some_function(void); +void t10() { + (void*) some_function(); //expected-warning {{expression result unused; should this cast be to 'void'?}} +} |