On Dec 11, 2009, at 11:25 PM, Douglas Gregor wrote: > Author: dgregor > Date: Sat Dec 12 01:25:49 2009 > New Revision: 91210 > > URL: http://llvm.org/viewvc/llvm-project?rev=91210&view=rev > Log: > Suppress warnings and errors about certain uses of non-POD types (in > __builtin_offsetof, passing through an ellipsis) when we're in an > unevaluated context. This is the first part of the fix to PR5761, > which deals with the simple case of an unevaluated context.
Thanks Doug, I feel bad turning this into an error :). However, it seems bad to duplicate this switch like this into each place that wants to emit a "runtime error". Would it make sense for the individual diagnostic producing cases to make a partial diagnostic and pass it into code that either ignores it, emits it, or buffers it? -Chris > > Modified: > cfe/trunk/lib/Sema/SemaExpr.cpp > cfe/trunk/test/SemaCXX/offsetof.cpp > cfe/trunk/test/SemaCXX/vararg-non-pod.cpp > > Modified: cfe/trunk/lib/Sema/SemaExpr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=91210&r1=91209&r2=91210&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Dec 12 01:25:49 2009 > @@ -259,15 +259,39 @@ > DefaultArgumentPromotion(Expr); > > if (Expr->getType()->isObjCInterfaceType()) { > - Diag(Expr->getLocStart(), > - diag::err_cannot_pass_objc_interface_to_vararg) > - << Expr->getType() << CT; > - return true; > + switch (ExprEvalContexts.back().Context ) { > + case Unevaluated: > + // The argument will never be evaluated, so don't complain. > + break; > + > + case PotentiallyEvaluated: > + Diag(Expr->getLocStart(), > + diag::err_cannot_pass_objc_interface_to_vararg) > + << Expr->getType() << CT; > + return true; > + > + case PotentiallyPotentiallyEvaluated: > + // FIXME: queue it! > + break; > + } > } > > - if (!Expr->getType()->isPODType()) > - Diag(Expr->getLocStart(), diag::warn_cannot_pass_non_pod_arg_to_vararg) > - << Expr->getType() << CT; > + if (!Expr->getType()->isPODType()) { > + switch (ExprEvalContexts.back().Context ) { > + case Unevaluated: > + // The argument will never be evaluated, so don't complain. > + break; > + > + case PotentiallyEvaluated: > + Diag(Expr->getLocStart(), diag::warn_cannot_pass_non_pod_arg_to_vararg) > + << Expr->getType() << CT; > + break; > + > + case PotentiallyPotentiallyEvaluated: > + // FIXME: queue it! > + break; > + } > + } > > return false; > } > @@ -6451,10 +6475,23 @@ > RecordDecl *RD = RC->getDecl(); > if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { > if (!CRD->isPOD() && !DidWarnAboutNonPOD) { > - ExprError(Diag(BuiltinLoc, diag::warn_offsetof_non_pod_type) > - << SourceRange(CompPtr[0].LocStart, OC.LocEnd) > - << Res->getType()); > - DidWarnAboutNonPOD = true; > + switch (ExprEvalContexts.back().Context ) { > + case Unevaluated: > + // The argument will never be evaluated, so don't complain. > + break; > + > + case PotentiallyEvaluated: > + ExprError(Diag(BuiltinLoc, diag::warn_offsetof_non_pod_type) > + << SourceRange(CompPtr[0].LocStart, OC.LocEnd) > + << Res->getType()); > + DidWarnAboutNonPOD = true; > + break; > + > + case PotentiallyPotentiallyEvaluated: > + // FIXME: Queue it! > + DidWarnAboutNonPOD = true; > + break; > + } > } > } > > > Modified: cfe/trunk/test/SemaCXX/offsetof.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/offsetof.cpp?rev=91210&r1=91209&r2=91210&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/offsetof.cpp (original) > +++ cfe/trunk/test/SemaCXX/offsetof.cpp Sat Dec 12 01:25:49 2009 > @@ -16,3 +16,5 @@ > struct Base { int x; }; > struct Derived : Base { int y; }; > int o = __builtin_offsetof(Derived, x); // expected-warning{{offset of on > non-POD type}} > + > +const int o2 = sizeof(__builtin_offsetof(Derived, x)); > > 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=91210&r1=91209&r2=91210&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/vararg-non-pod.cpp (original) > +++ cfe/trunk/test/SemaCXX/vararg-non-pod.cpp Sat Dec 12 01:25:49 2009 > @@ -66,3 +66,12 @@ > E e(10, c); // expected-warning{{cannot pass object of non-POD type 'class > C' through variadic constructor; call will abort at runtime}} > (void)E(10, c); // expected-warning{{cannot pass object of non-POD type > 'class C' through variadic constructor; call will abort at runtime}} > } > + > +// PR5761: unevaluated operands and the non-POD warning > +class Foo { > + public: > + Foo() {} > +}; > + > +int Helper(...); > +const int size = sizeof(Helper(Foo())); > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
