[cfe-commits] r144273 - in /cfe/trunk: lib/AST/ExprConstant.cpp test/SemaCXX/constant-expression-cxx11.cpp
Daniel Dunbar
daniel at zuster.org
Thu Nov 10 09:54:38 PST 2011
I attached a test case, repro with clang -c t.ii.
- Daniel
On Thu, Nov 10, 2011 at 9:49 AM, Devang Patel <dpatel at apple.com> wrote:
> Richard,
>
> I am reverting this patch because it is causing clang self-host build failure with following assertion. Please investigate.
>
> Assertion failed: ((E->isGLValue() || E->getType()->isFunctionType() || E->getType()->isVoidType() || isa<CXXTemporaryObjectExpr>(E)) && "can't evaluate expression as an lvalue"), function EvaluateLValue, file /Volumes/Lalgate/clean/llvm/tools/clang/lib/AST/ExprConstant.cpp, line 1549.
> 0 clang 0x000000010b795a52 _ZL15PrintStackTracePv + 34
> 1 clang 0x000000010b796049 _ZL13SignalHandleri + 777
> 2 libsystem_c.dylib 0x00007fff84106cfa _sigtramp + 26
> 3 libsystem_c.dylib 0x00007f9b09a7dc80 _sigtramp + 18446743642159148960
> 4 clang 0x000000010b795c96 abort + 22
> 5 clang 0x000000010b795c57 __assert_rtn + 55
> 6 clang 0x000000010ac52b84 _ZL14EvaluateLValuePKN5clang4ExprERN12_GLOBAL__N_16LValueERNS3_8EvalInfoE + 132
> 7 clang 0x000000010ac5d115 (anonymous namespace)::IntExprEvaluator::VisitCallExpr(clang::CallExpr const*) + 1765
> 8 clang 0x000000010ac594d0 clang::StmtVisitorBase<clang::make_const_ptr, (anonymous namespace)::IntExprEvaluator, bool>::Visit(clang::Stmt const*) + 2000
> 9 clang 0x000000010ac50ec4 _ZL8EvaluateRN12_GLOBAL__N_17CCValueERNS_8EvalInfoEPKN5clang4ExprE + 388
> 10 clang 0x000000010ac50af2 clang::Expr::EvaluateAsRValue(clang::Expr::EvalResult&, clang::ASTContext const&) const + 306
> 11 clang 0x000000010ac521e9 clang::Expr::EvaluateAsBooleanCondition(bool&, clang::ASTContext const&) const + 57
> 12 clang 0x000000010aa2e21b (anonymous namespace)::CFGBuilder::Visit(clang::Stmt*, (anonymous namespace)::AddStmtChoice) + 11435
> 13 clang 0x000000010aa30137 (anonymous namespace)::CFGBuilder::VisitCompoundStmt(clang::CompoundStmt*) + 119
> 14 clang 0x000000010aa2efe4 (anonymous namespace)::CFGBuilder::Visit(clang::Stmt*, (anonymous namespace)::AddStmtChoice) + 14964
> 15 clang 0x000000010aa2626f clang::CFG::buildCFG(clang::Decl const*, clang::Stmt*, clang::ASTContext*, clang::CFG::BuildOptions const&) + 1519
> 16 clang 0x000000010aa22cbd clang::AnalysisDeclContext::getCFG() + 77
> 17 clang 0x000000010a6bdef5 clang::sema::AnalysisBasedWarnings::IssueWarnings(clang::sema::AnalysisBasedWarnings::Policy, clang::sema::FunctionScopeInfo*, clang::Decl const*, clang::BlockExpr const*) + 4149
> 18 clang 0x000000010a6d67af clang::Sema::PopFunctionOrBlockScope(clang::sema::AnalysisBasedWarnings::Policy const*, clang::Decl const*, clang::BlockExpr const*) + 95
> 19 clang 0x000000010a767cad clang::Sema::ActOnFinishFunctionBody(clang::Decl*, clang::Stmt*, bool) + 1501
> 20 clang 0x000000010a6ab204 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) + 244
> 21 clang 0x000000010a6b8d83 clang::Parser::ParseFunctionDefinition(clang::Parser::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&) + 2259
> 22 clang 0x000000010a66aacc clang::Parser::ParseDeclGroup(clang::Parser::ParsingDeclSpec&, unsigned int, bool, clang::SourceLocation*, clang::Parser::ForRangeInit*) + 1068
> 23 clang 0x000000010a6b7efa clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsingDeclSpec&, clang::AccessSpecifier) + 858
> 24 clang 0x000000010a6b80f9 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::AccessSpecifier) + 393
> 25 clang 0x000000010a6b70af clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::Parser::ParsingDeclSpec*) + 3311
> 26 clang 0x000000010a6b6347 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&) + 247
> 27 clang 0x000000010a66079d clang::ParseAST(clang::Sema&, bool) + 317
> 28 clang 0x000000010a62e5f7 clang::CodeGenAction::ExecuteAction() + 1031
> 29 clang 0x000000010a434a9b clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 955
> 30 clang 0x000000010a41d4c8 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 2792
> 31 clang 0x000000010a414ce7 cc1_main(char const**, char const**, char const*, void*) + 5287
> 32 clang 0x000000010a419852 main + 706
> 33 clang 0x000000010a413834 start + 52
> 34 clang 0x0000000000000050 start + 18446744069242538064
> Stack dump:
>
> -
> Devang
>
>
> On Nov 10, 2011, at 1:31 AM, Richard Smith wrote:
>
>> Author: rsmith
>> Date: Thu Nov 10 03:31:24 2011
>> New Revision: 144273
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=144273&view=rev
>> Log:
>> Constant expression evaluation: support for constexpr member functions.
>>
>> Modified:
>> cfe/trunk/lib/AST/ExprConstant.cpp
>> cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
>>
>> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=144273&r1=144272&r2=144273&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
>> +++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Nov 10 03:31:24 2011
>> @@ -1029,8 +1029,9 @@
>> }
>>
>> /// Evaluate a function call.
>> -static bool HandleFunctionCall(ArrayRef<const Expr*> Args, const Stmt *Body,
>> - EvalInfo &Info, CCValue &Result) {
>> +static bool HandleFunctionCall(const LValue *This, ArrayRef<const Expr*> Args,
>> + const Stmt *Body, EvalInfo &Info,
>> + CCValue &Result) {
>> // FIXME: Implement a proper call limit, along with a command-line flag.
>> if (Info.NumCalls >= 1000000 || Info.CallStackDepth >= 512)
>> return false;
>> @@ -1039,16 +1040,15 @@
>> if (!EvaluateArgs(Args, ArgValues, Info))
>> return false;
>>
>> - // FIXME: Pass in 'this' for member functions.
>> - const LValue *This = 0;
>> CallStackFrame Frame(Info, This, ArgValues.data());
>> return EvaluateStmt(Result, Info, Body) == ESR_Returned;
>> }
>>
>> /// Evaluate a constructor call.
>> -static bool HandleConstructorCall(ArrayRef<const Expr*> Args,
>> +static bool HandleConstructorCall(const LValue &This,
>> + ArrayRef<const Expr*> Args,
>> const CXXConstructorDecl *Definition,
>> - EvalInfo &Info, const LValue &This,
>> + EvalInfo &Info,
>> APValue &Result) {
>> if (Info.NumCalls >= 1000000 || Info.CallStackDepth >= 512)
>> return false;
>> @@ -1305,39 +1305,64 @@
>> const Expr *Callee = E->getCallee();
>> QualType CalleeType = Callee->getType();
>>
>> - // FIXME: Handle the case where Callee is a (parenthesized) MemberExpr for a
>> - // non-static member function.
>> - if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember))
>> - return DerivedError(E);
>> -
>> - if (!CalleeType->isFunctionType() && !CalleeType->isFunctionPointerType())
>> - return DerivedError(E);
>> -
>> - CCValue Call;
>> - if (!Evaluate(Call, Info, Callee) || !Call.isLValue() ||
>> - !Call.getLValueBase() || !Call.getLValueOffset().isZero())
>> - return DerivedError(Callee);
>> -
>> const FunctionDecl *FD = 0;
>> - if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Call.getLValueBase()))
>> - FD = dyn_cast<FunctionDecl>(DRE->getDecl());
>> - else if (const MemberExpr *ME = dyn_cast<MemberExpr>(Call.getLValueBase()))
>> + LValue *This = 0, ThisVal;
>> + llvm::ArrayRef<const Expr*> Args(E->getArgs(), E->getNumArgs());
>> +
>> + // Extract function decl and 'this' pointer from the callee.
>> + if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) {
>> + const MemberExpr *ME = dyn_cast<MemberExpr>(Callee->IgnoreParens());
>> + // FIXME: Handle a BinaryOperator callee ('.*' or '->*').
>> + if (!ME)
>> + return DerivedError(Callee);
>> + if (ME->isArrow()) {
>> + if (!EvaluatePointer(ME->getBase(), ThisVal, Info))
>> + return DerivedError(ME);
>> + } else {
>> + if (!EvaluateLValue(ME->getBase(), ThisVal, Info))
>> + return DerivedError(ME);
>> + }
>> + This = &ThisVal;
>> FD = dyn_cast<FunctionDecl>(ME->getMemberDecl());
>> - if (!FD)
>> - return DerivedError(Callee);
>> + if (!FD)
>> + return DerivedError(ME);
>> + } else if (CalleeType->isFunctionPointerType()) {
>> + CCValue Call;
>> + if (!Evaluate(Call, Info, Callee) || !Call.isLValue() ||
>> + !Call.getLValueBase() || !Call.getLValueOffset().isZero())
>> + return DerivedError(Callee);
>> +
>> + const Expr *Base = Call.getLValueBase();
>> +
>> + if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base))
>> + FD = dyn_cast<FunctionDecl>(DRE->getDecl());
>> + else if (const MemberExpr *ME = dyn_cast<MemberExpr>(Base))
>> + FD = dyn_cast<FunctionDecl>(ME->getMemberDecl());
>> + if (!FD)
>> + return DerivedError(Callee);
>> +
>> + // Overloaded operator calls to member functions are represented as normal
>> + // calls with 'this' as the first argument.
>> + const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
>> + if (MD && !MD->isStatic()) {
>> + if (!EvaluateLValue(Args[0], ThisVal, Info))
>> + return DerivedError(Args[0]);
>> + This = &ThisVal;
>> + Args = Args.slice(1);
>> + }
>>
>> - // Don't call function pointers which have been cast to some other type.
>> - if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType()))
>> - return DerivedError(E);
>> + // Don't call function pointers which have been cast to some other type.
>> + if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType()))
>> + return DerivedError(E);
>> + }
>>
>> const FunctionDecl *Definition;
>> Stmt *Body = FD->getBody(Definition);
>> CCValue CCResult;
>> APValue Result;
>> - llvm::ArrayRef<const Expr*> Args(E->getArgs(), E->getNumArgs());
>>
>> if (Body && Definition->isConstexpr() && !Definition->isInvalidDecl() &&
>> - HandleFunctionCall(Args, Body, Info, CCResult) &&
>> + HandleFunctionCall(This, Args, Body, Info, CCResult) &&
>> CheckConstantExpression(CCResult, Result))
>> return DerivedSuccess(CCValue(Result, CCValue::GlobalValue()), E);
>>
>> @@ -1890,8 +1915,8 @@
>> return Visit(ME->GetTemporaryExpr());
>>
>> llvm::ArrayRef<const Expr*> Args(E->getArgs(), E->getNumArgs());
>> - return HandleConstructorCall(Args, cast<CXXConstructorDecl>(Definition),
>> - Info, This, Result);
>> + return HandleConstructorCall(This, Args, cast<CXXConstructorDecl>(Definition),
>> + Info, Result);
>> }
>>
>> static bool EvaluateRecord(const Expr *E, const LValue &This,
>>
>> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=144273&r1=144272&r2=144273&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Thu Nov 10 03:31:24 2011
>> @@ -608,3 +608,35 @@
>> static_assert_fold((&(u[1]) + 1 + 1)->b == 3, "");
>>
>> }
>> +
>> +namespace Complex {
>> +
>> +class complex {
>> + int re, im;
>> +public:
>> + constexpr complex(int re = 0, int im = 0) : re(re), im(im) {}
>> + constexpr complex(const complex &o) : re(o.re), im(o.im) {}
>> + constexpr complex operator-() const { return complex(-re, -im); }
>> + friend constexpr complex operator+(const complex &l, const complex &r) {
>> + return complex(l.re + r.re, l.im + r.im);
>> + }
>> + friend constexpr complex operator-(const complex &l, const complex &r) {
>> + return l + -r;
>> + }
>> + friend constexpr complex operator*(const complex &l, const complex &r) {
>> + return complex(l.re * r.re - l.im * r.im, l.re * r.im + l.im * r.re);
>> + }
>> + friend constexpr bool operator==(const complex &l, const complex &r) {
>> + return l.re == r.re && l.im == r.im;
>> + }
>> + constexpr int real() const { return re; }
>> + constexpr int imag() const { return im; }
>> +};
>> +
>> +constexpr complex i = complex(0, 1);
>> +constexpr complex k = (3 + 4*i) * (6 - 4*i);
>> +static_assert_fold(k.real() == 34, "");
>> +static_assert_fold(k.imag() == 12, "");
>> +static_assert_fold(k - 34 == 12*i, "");
>> +
>> +}
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: t.ii
Type: application/octet-stream
Size: 769205 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20111110/744f069f/attachment.obj>
More information about the cfe-commits
mailing list