[cfe-commits] r148271 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/SemaCXX/vararg-non-pod.cpp
Eli Friedman
eli.friedman at gmail.com
Mon Jan 16 17:17:47 PST 2012
Author: efriedma
Date: Mon Jan 16 19:17:46 2012
New Revision: 148271
URL: http://llvm.org/viewvc/llvm-project?rev=148271&view=rev
Log:
Change the behavior of the lvalue-to-rvalue conversion for varargs in PotentiallyPotentiallyEvaluated contexts so that we model it in a sane way in most cases, and give up for the edge case which hopefully doesn't matter too much.
In preparation for correctly treating sizeof() as a PotentiallyPotentiallyEvaluated context.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/SemaCXX/vararg-non-pod.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=148271&r1=148270&r2=148271&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jan 16 19:17:46 2012
@@ -4318,6 +4318,10 @@
"cannot pass object with interface type %0 by-value through variadic "
"%select{function|block|method}1">;
+def err_cannot_pass_non_pod_to_vararg_ppe : Error<
+ "passing object of type %0 to variadic call in a context "
+ "which is potentially evaluatable, but not obviously "
+ "potentially evaluatable, is not yet implemented">;
def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
"cannot pass object of %select{non-POD|non-trivial}0 type %1 through variadic"
" %select{function|block|method|constructor}2; call will abort at runtime">,
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=148271&r1=148270&r2=148271&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jan 16 19:17:46 2012
@@ -486,17 +486,34 @@
// has a class type, the conversion copy-initializes a temporary
// of type T from the glvalue and the result of the conversion
// is a prvalue for the temporary.
- // FIXME: add some way to gate this entire thing for correctness in
- // potentially potentially evaluated contexts.
- if (getLangOptions().CPlusPlus && E->isGLValue() &&
- ExprEvalContexts.back().Context != Unevaluated) {
- ExprResult Temp = PerformCopyInitialization(
- InitializedEntity::InitializeTemporary(E->getType()),
- E->getExprLoc(),
- Owned(E));
- if (Temp.isInvalid())
- return ExprError();
- E = Temp.get();
+ // This requirement has some strange effects for
+ // PotentiallyPotentiallyEvaluated contexts; specifically, doing precisely
+ // what the standard requires involves mutating the AST once we decide
+ // whether an expression is potentially evaluated. Rather than actually try and
+ // model this correctly, we just make sure to handle the important cases:
+ // for types with a trivial copy constructor/destructor, we build the AST
+ // as if it were potentially evaluated, and we give an error in other cases
+ // if the context turns out to be potentially evaluatable.
+ // FIXME: If anyone actually cares about this case, try to implement
+ // it correctly, or at least improve the diagnostic output a bit.
+ if (getLangOptions().CPlusPlus && E->isGLValue()) {
+ if (ExprEvalContexts.back().Context == PotentiallyPotentiallyEvaluated &&
+ E->getType()->isRecordType() &&
+ (!E->getType().isTriviallyCopyableType(Context) ||
+ E->getType().isDestructedType())) {
+ ExprEvalContexts.back()
+ .addDiagnostic(E->getExprLoc(),
+ PDiag(diag::err_cannot_pass_non_pod_to_vararg_ppe)
+ << E->getType());
+ } else if (ExprEvalContexts.back().Context != Unevaluated) {
+ ExprResult Temp = PerformCopyInitialization(
+ InitializedEntity::InitializeTemporary(E->getType()),
+ E->getExprLoc(),
+ Owned(E));
+ if (Temp.isInvalid())
+ return ExprError();
+ E = Temp.get();
+ }
}
return Owned(E);
Modified: cfe/trunk/test/SemaCXX/vararg-non-pod.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vararg-non-pod.cpp?rev=148271&r1=148270&r2=148271&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/vararg-non-pod.cpp (original)
+++ cfe/trunk/test/SemaCXX/vararg-non-pod.cpp Mon Jan 16 19:17:46 2012
@@ -88,7 +88,8 @@
int eat_base(...);
void test_typeid(Base &base) {
- (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}}
+ (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}} \
+ // expected-error {{potentially evaluatable, but not obviously potentially evaluatable}}
(void)typeid(eat_base(base)); // okay
}
More information about the cfe-commits
mailing list