[cfe-commits] r144273 - in /cfe/trunk: lib/AST/ExprConstant.cpp test/SemaCXX/constant-expression-cxx11.cpp
Devang Patel
dpatel at apple.com
Thu Nov 10 09:49:27 PST 2011
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
More information about the cfe-commits
mailing list