diff options
author | Anders Carlsson <andersca@mac.com> | 2009-11-23 21:47:44 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-11-23 21:47:44 +0000 |
commit | a4c98cd60e7151ea6eccfc677742bdbcf58d2a55 (patch) | |
tree | 321354a9aed828c722be40f9edbfe7dc9db06e88 | |
parent | 60bce3ef20a4c9684e3825cdd739fefb9810327d (diff) |
Convert the && and || operands to bool using standard conversions. Fixes PR5593.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89704 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 40 | ||||
-rw-r--r-- | test/CodeGenCXX/member-function-pointers.cpp | 9 |
2 files changed, 40 insertions, 9 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 15b5319737..237472f560 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4852,19 +4852,41 @@ inline QualType Sema::CheckBitwiseOperands( inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] Expr *&lex, Expr *&rex, SourceLocation Loc) { - UsualUnaryConversions(lex); - UsualUnaryConversions(rex); + if (!Context.getLangOptions().CPlusPlus) { + UsualUnaryConversions(lex); + UsualUnaryConversions(rex); - if (!lex->getType()->isScalarType() || !rex->getType()->isScalarType()) - return InvalidOperands(Loc, lex, rex); + if (!lex->getType()->isScalarType() || !rex->getType()->isScalarType()) + return InvalidOperands(Loc, lex, rex); - if (Context.getLangOptions().CPlusPlus) { - // C++ [expr.log.and]p2 - // C++ [expr.log.or]p2 - return Context.BoolTy; + return Context.IntTy; } + + // C++ [expr.log.and]p1 + // C++ [expr.log.or]p1 + // The operands are both implicitly converted to type bool (clause 4). + StandardConversionSequence LHS; + if (!IsStandardConversion(lex, Context.BoolTy, + /*InOverloadResolution=*/false, LHS)) + return InvalidOperands(Loc, lex, rex); - return Context.IntTy; + if (PerformImplicitConversion(lex, Context.BoolTy, LHS, + "passing", /*IgnoreBaseAccess=*/false)) + return InvalidOperands(Loc, lex, rex); + + StandardConversionSequence RHS; + if (!IsStandardConversion(rex, Context.BoolTy, + /*InOverloadResolution=*/false, RHS)) + return InvalidOperands(Loc, lex, rex); + + if (PerformImplicitConversion(rex, Context.BoolTy, RHS, + "passing", /*IgnoreBaseAccess=*/false)) + return InvalidOperands(Loc, lex, rex); + + // C++ [expr.log.and]p2 + // C++ [expr.log.or]p2 + // The result is a bool. + return Context.BoolTy; } /// IsReadonlyProperty - Verify that otherwise a valid l-value expression diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp index 56696712e4..bba9962066 100644 --- a/test/CodeGenCXX/member-function-pointers.cpp +++ b/test/CodeGenCXX/member-function-pointers.cpp @@ -91,3 +91,12 @@ namespace PR5138 { void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar; } + +// PR5593 +namespace PR5593 { + struct A { }; + + bool f(void (A::*f)()) { + return f && f; + } +} |