[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