From: Chris Lattner Date: Sat, 17 Oct 2009 04:24:20 +0000 (+0000) Subject: Fix PR5211: codegen shouldn't assume that the result of ||/&& is int X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7804bcba90bf5ea8ec6cd0f6cc9a64577f1a9259;p=clang Fix PR5211: codegen shouldn't assume that the result of ||/&& is int anymore. In C++ it is bool. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84308 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index cc81256032..422e2b65bc 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1379,18 +1379,20 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { } Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { + const llvm::Type *ResTy = ConvertType(E->getType()); + // If we have 0 && RHS, see if we can elide RHS, if so, just return 0. // If we have 1 && X, just emit X without inserting the control flow. if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getLHS())) { if (Cond == 1) { // If we have 1 && X, just emit X. Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); - // ZExt result to int. - return Builder.CreateZExt(RHSCond, CGF.LLVMIntTy, "land.ext"); + // ZExt result to int or bool. + return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext"); } - // 0 && RHS: If it is safe, just elide the RHS, and return 0. + // 0 && RHS: If it is safe, just elide the RHS, and return 0/false. if (!CGF.ContainsLabel(E->getRHS())) - return llvm::Constant::getNullValue(CGF.LLVMIntTy); + return llvm::Constant::getNullValue(ResTy); } llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end"); @@ -1423,22 +1425,24 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { PN->addIncoming(RHSCond, RHSBlock); // ZExt result to int. - return Builder.CreateZExt(PN, CGF.LLVMIntTy, "land.ext"); + return Builder.CreateZExtOrBitCast(PN, ResTy, "land.ext"); } Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { + const llvm::Type *ResTy = ConvertType(E->getType()); + // If we have 1 || RHS, see if we can elide RHS, if so, just return 1. // If we have 0 || X, just emit X without inserting the control flow. if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getLHS())) { if (Cond == -1) { // If we have 0 || X, just emit X. Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); - // ZExt result to int. - return Builder.CreateZExt(RHSCond, CGF.LLVMIntTy, "lor.ext"); + // ZExt result to int or bool. + return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext"); } - // 1 || RHS: If it is safe, just elide the RHS, and return 1. + // 1 || RHS: If it is safe, just elide the RHS, and return 1/true. if (!CGF.ContainsLabel(E->getRHS())) - return llvm::ConstantInt::get(CGF.LLVMIntTy, 1); + return llvm::ConstantInt::get(ResTy, 1); } llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end"); @@ -1474,7 +1478,7 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { PN->addIncoming(RHSCond, RHSBlock); // ZExt result to int. - return Builder.CreateZExt(PN, CGF.LLVMIntTy, "lor.ext"); + return Builder.CreateZExtOrBitCast(PN, ResTy, "lor.ext"); } Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) { diff --git a/test/CodeGenCXX/expr.cpp b/test/CodeGenCXX/expr.cpp index ae5b0e644f..4dc97c47aa 100644 --- a/test/CodeGenCXX/expr.cpp +++ b/test/CodeGenCXX/expr.cpp @@ -1,5 +1,12 @@ // RUN: clang-cc -emit-llvm -x c++ < %s -void f(int x) { +void test0(int x) { if (x != 0) return; } + + +// PR5211 +void test1() { + char *xpto; + while ( true && xpto[0] ); +}