summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorGeorge Burgess IV <george.burgess.iv@gmail.com>2017-01-09 04:12:14 +0000
committerGeorge Burgess IV <george.burgess.iv@gmail.com>2017-01-09 04:12:14 +0000
commit177399e2277c3dbecfc00d83f94784cc7bfdd4d6 (patch)
treefd3bdd091ba2ff8942eec3c67d793d6afc236b67 /clang/lib/AST/ExprConstant.cpp
parentff567a8ba200e05cd92015403302983510959766 (diff)
downloadbcm5719-llvm-177399e2277c3dbecfc00d83f94784cc7bfdd4d6.tar.gz
bcm5719-llvm-177399e2277c3dbecfc00d83f94784cc7bfdd4d6.zip
Add the diagnose_if attribute to clang.
`diagnose_if` can be used to have clang emit either warnings or errors for function calls that meet user-specified conditions. For example: ``` constexpr int foo(int a) __attribute__((diagnose_if(a > 10, "configurations with a > 10 are " "expensive.", "warning"))); int f1 = foo(9); int f2 = foo(10); // warning: configuration with a > 10 are expensive. int f3 = foo(f2); ``` It currently only emits diagnostics in cases where the condition is guaranteed to always be true. So, the following code will emit no warnings: ``` constexpr int bar(int a) { foo(a); return 0; } constexpr int i = bar(10); ``` We hope to support optionally emitting diagnostics for cases like that (and emitting runtime checks) in the future. Release notes will appear shortly. :) Differential Revision: https://reviews.llvm.org/D27424 llvm-svn: 291418
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r--clang/lib/AST/ExprConstant.cpp19
1 files changed, 17 insertions, 2 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 18206e5e0ee..fe77c7f6f3b 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10410,10 +10410,25 @@ bool Expr::isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result,
bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
const FunctionDecl *Callee,
- ArrayRef<const Expr*> Args) const {
+ ArrayRef<const Expr*> Args,
+ const Expr *This) const {
Expr::EvalStatus Status;
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
+ LValue ThisVal;
+ const LValue *ThisPtr = nullptr;
+ if (This) {
+#ifndef NDEBUG
+ auto *MD = dyn_cast<CXXMethodDecl>(Callee);
+ assert(MD && "Don't provide `this` for non-methods.");
+ assert(!MD->isStatic() && "Don't provide `this` for static methods.");
+#endif
+ if (EvaluateObjectArgument(Info, This, ThisVal))
+ ThisPtr = &ThisVal;
+ if (Info.EvalStatus.HasSideEffects)
+ return false;
+ }
+
ArgVector ArgValues(Args.size());
for (ArrayRef<const Expr*>::iterator I = Args.begin(), E = Args.end();
I != E; ++I) {
@@ -10426,7 +10441,7 @@ bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
}
// Build fake call to Callee.
- CallStackFrame Frame(Info, Callee->getLocation(), Callee, /*This*/nullptr,
+ CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
ArgValues.data());
return Evaluate(Value, Info, this) && !Info.EvalStatus.HasSideEffects;
}
OpenPOWER on IntegriCloud