summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2017-06-02 13:31:37 +0200
committerStephan Bergmann <sbergman@redhat.com>2017-06-02 13:31:37 +0200
commit95645cbf0a220c338600130bdeca49743b252972 (patch)
tree9207b66ed98ea8f24573b6e1214d642314d68ad8 /compilerplugins
parentff77fdbe29f0cf93f93d6e75ba5ca101e2e321a5 (diff)
Improved loplugin:redundantcast const_cast handling
Change-Id: I4c24ff5d9d5e74bef2a4040c6308c504282af55d
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/redundantcast.cxx20
-rw-r--r--compilerplugins/clang/test/redundantcast.cxx112
2 files changed, 119 insertions, 13 deletions
diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx
index 6bc97e5351a3..6d740ddca883 100644
--- a/compilerplugins/clang/redundantcast.cxx
+++ b/compilerplugins/clang/redundantcast.cxx
@@ -37,9 +37,12 @@ bool isVoidPointer(QualType type) {
}
bool isRedundantConstCast(CXXConstCastExpr const * expr) {
- return expr->getTypeAsWritten().getCanonicalType().getTypePtr()
- == (expr->getSubExprAsWritten()->getType().getCanonicalType()
- .getTypePtr());
+ auto const sub = compat::getSubExprAsWritten(expr);
+ return
+ (expr->getType().getCanonicalType()
+ == sub->getType().getCanonicalType())
+ && (expr->getValueKind() != VK_XValue
+ || sub->getValueKind() == VK_XValue);
}
bool isArithmeticOp(Expr const * expr) {
@@ -511,11 +514,14 @@ bool RedundantCast::VisitCXXConstCastExpr(CXXConstCastExpr const * expr) {
return true;
}
if (isRedundantConstCast(expr)) {
+ auto const sub = compat::getSubExprAsWritten(expr);
report(
- DiagnosticsEngine::Warning, "redundant const_cast from %0 to %1",
- expr->getExprLoc())
- << expr->getSubExprAsWritten()->getType()
- << expr->getTypeAsWritten() << expr->getSourceRange();
+ DiagnosticsEngine::Warning,
+ "redundant const_cast from %0 %1 to %2 %3", expr->getExprLoc())
+ << sub->getType() << printExprValueKind(sub->getValueKind())
+ << expr->getTypeAsWritten()
+ << printExprValueKind(expr->getValueKind())
+ << expr->getSourceRange();
}
return true;
}
diff --git a/compilerplugins/clang/test/redundantcast.cxx b/compilerplugins/clang/test/redundantcast.cxx
index 6e5a8d42e589..1d2646a0f463 100644
--- a/compilerplugins/clang/test/redundantcast.cxx
+++ b/compilerplugins/clang/test/redundantcast.cxx
@@ -19,24 +19,124 @@ void testConstCast() {
char const * p2;
p1 = nullptr;
p2 = "";
- f1(const_cast<char *>(p1)); // expected-error {{redundant const_cast from 'char *' to 'char *' [loplugin:redundantcast]}}
- f1(const_cast<char * const>(p1)); // expected-error {{redundant const_cast from 'char *' to 'char *const' [loplugin:redundantcast]}}
+ f1(const_cast<char *>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *' prvalue [loplugin:redundantcast]}}
+ f1(const_cast<char * const>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *const' prvalue [loplugin:redundantcast]}}
f1(const_cast<char *>(p2));
f1(const_cast<char * const>(p2));
- f2(const_cast<char *>(p1)); // expected-error {{redundant const_cast from 'char *' to 'char *' [loplugin:redundantcast]}}
- f2(const_cast<char * const>(p1)); // expected-error {{redundant const_cast from 'char *' to 'char *const' [loplugin:redundantcast]}}
+ f2(const_cast<char *>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *' prvalue [loplugin:redundantcast]}}
+ f2(const_cast<char * const>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *const' prvalue [loplugin:redundantcast]}}
f2(const_cast<char const *>(p1));
f2(const_cast<char const * const>(p1));
f2(const_cast<char *>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'char *', result is implicitly cast to 'const char *' [loplugin:redundantcast]}}
f2(const_cast<char * const>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'char *', result is implicitly cast to 'const char *' [loplugin:redundantcast]}}
- f2(const_cast<char const *>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'const char *' [loplugin:redundantcast]}}
- f2(const_cast<char const * const>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'const char *const' [loplugin:redundantcast]}}
+ f2(const_cast<char const *>(p2)); // expected-error {{redundant const_cast from 'const char *' lvalue to 'const char *' prvalue [loplugin:redundantcast]}}
+ f2(const_cast<char const * const>(p2)); // expected-error {{redundant const_cast from 'const char *' lvalue to 'const char *const' prvalue [loplugin:redundantcast]}}
S const s{};
const_cast<S &>(s).f1();
const_cast<S &>(s).f2(); // expected-error {{redundant const_cast from 'const S' to 'S', result is implicitly cast to 'const S' [loplugin:redundantcast]}}
const_cast<S &>(s).f3();
s.f3();
+
+ // non-class lvalue, non-const:
+ int ni{};
+// (void) const_cast<int>(ni);
+ (void) const_cast<int &>(ni); // expected-error {{redundant const_cast from 'int' lvalue to 'int &' lvalue [loplugin:redundantcast]}}
+ (void) const_cast<int &&>(ni);
+// (void) const_cast<int const>(ni);
+ (void) const_cast<int const &>(ni);
+ (void) const_cast<int const &&>(ni);
+
+ // non-class lvalue, const:
+ int const ci{};
+// (void) const_cast<int>(ci);
+ (void) const_cast<int &>(ci);
+ (void) const_cast<int &&>(ci);
+// (void) const_cast<int const>(ci);
+ (void) const_cast<int const &>(ci); // expected-error {{redundant const_cast from 'const int' lvalue to 'const int &' lvalue [loplugin:redundantcast]}}
+ (void) const_cast<int const &&>(ci);
+
+ // non-class xvalue, non-const:
+// (void) const_cast<int>(nix());
+// (void) const_cast<int &>(nix());
+ (void) const_cast<int &&>(nix()); // expected-error {{redundant const_cast from 'int' xvalue to 'int &&' xvalue [loplugin:redundantcast]}}
+// (void) const_cast<int const>(nix());
+// (void) const_cast<int const &>(nix());
+ (void) const_cast<int const &&>(nix());
+
+ // non-class xvalue, const:
+// (void) const_cast<int>(cix());
+// (void) const_cast<int &>(cix());
+ (void) const_cast<int &&>(cix());
+// (void) const_cast<int const>(cix());
+// (void) const_cast<int const &>(cix());
+ (void) const_cast<int const &&>(cix()); // expected-error {{redundant const_cast from 'const int' xvalue to 'const int &&' xvalue [loplugin:redundantcast]}}
+
+ // non-class prvalue, non-const:
+// (void) const_cast<int>(nir());
+// (void) const_cast<int &>(nir());
+// (void) const_cast<int &&>(nir());
+// (void) const_cast<int const>(nir());
+// (void) const_cast<int const &>(nir());
+// (void) const_cast<int const &&>(nir());
+
+ // non-class prvalue, const:
+// (void) const_cast<int>(cir());
+// (void) const_cast<int &>(cir());
+// (void) const_cast<int &&>(cir());
+// (void) const_cast<int const>(cir());
+// (void) const_cast<int const &>(cir());
+// (void) const_cast<int const &&>(cir());
+
+ // class lvalue, non-const:
+ S ns{};
+// (void) const_cast<S>(ns);
+ (void) const_cast<S &>(ns); // expected-error {{redundant const_cast from 'S' lvalue to 'S &' lvalue [loplugin:redundantcast]}}
+ (void) const_cast<S &&>(ns);
+// (void) const_cast<S const>(ns);
+ (void) const_cast<S const &>(ns);
+ (void) const_cast<S const &&>(ns);
+
+ // class lvalue, const:
+ S const cs{};
+// (void) const_cast<S>(cs);
+ (void) const_cast<S &>(cs);
+ (void) const_cast<S &&>(cs);
+// (void) const_cast<S const>(cs);
+ (void) const_cast<S const &>(cs); // expected-error {{redundant const_cast from 'const S' lvalue to 'const S &' lvalue [loplugin:redundantcast]}}
+ (void) const_cast<S const &&>(cs);
+
+ // class xvalue, non-const:
+// (void) const_cast<S>(nsx());
+// (void) const_cast<S &>(nsx());
+ (void) const_cast<S &&>(nsx()); // expected-error {{redundant const_cast from 'S' xvalue to 'S &&' xvalue [loplugin:redundantcast]}}
+// (void) const_cast<S const>(nsx());
+// (void) const_cast<S const &>(nsx());
+ (void) const_cast<S const &&>(nsx());
+
+ // class xvalue, const:
+// (void) const_cast<S>(csx());
+// (void) const_cast<S &>(csx());
+ (void) const_cast<S &&>(csx());
+// (void) const_cast<S const>(csx());
+// (void) const_cast<S const &>(csx());
+ (void) const_cast<S const &&>(csx()); // expected-error {{redundant const_cast from 'const S' xvalue to 'const S &&' xvalue [loplugin:redundantcast]}}
+
+ // class prvalue, non-const:
+// (void) const_cast<S>(nsr());
+// (void) const_cast<S &>(nsr());
+ (void) const_cast<S &&>(nsr());
+// (void) const_cast<S const>(nsr());
+// (void) const_cast<S const &>(nsr());
+ (void) const_cast<S const &&>(nsr());
+
+ // class prvalue, const:
+// (void) const_cast<S>(csr());
+// (void) const_cast<S &>(csr());
+ (void) const_cast<S &&>(csr());
+// (void) const_cast<S const>(csr());
+// (void) const_cast<S const &>(csr());
+ (void) const_cast<S const &&>(csr());
}
void testStaticCast() {