]> granicus.if.org Git - clang/commitdiff
Convert the && and || operands to bool using standard conversions. Fixes PR5593.
authorAnders Carlsson <andersca@mac.com>
Mon, 23 Nov 2009 21:47:44 +0000 (21:47 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 23 Nov 2009 21:47:44 +0000 (21:47 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89704 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/CodeGenCXX/member-function-pointers.cpp

index 15b53197372061b5490471f8f3bae1734b02523e..237472f56066252e4910c3720dad9cd3a947d3c5 100644 (file)
@@ -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
index 56696712e4837c4be1b1fa61f479fcce0ff810ff..bba996206644d07799ff3954f3cda790f2b181f9 100644 (file)
@@ -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;
+  }
+}