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
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 15b5319..237472f 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4852,19 +4852,41 @@
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 5669671..bba9962 100644
--- a/test/CodeGenCXX/member-function-pointers.cpp
+++ b/test/CodeGenCXX/member-function-pointers.cpp
@@ -91,3 +91,12 @@
void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar;
}
+
+// PR5593
+namespace PR5593 {
+ struct A { };
+
+ bool f(void (A::*f)()) {
+ return f && f;
+ }
+}