summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp40
-rw-r--r--clang/test/CodeGenCXX/member-function-pointers.cpp9
2 files changed, 40 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 15b53197372..237472f5606 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/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/clang/test/CodeGenCXX/member-function-pointers.cpp b/clang/test/CodeGenCXX/member-function-pointers.cpp
index 56696712e48..bba99620664 100644
--- a/clang/test/CodeGenCXX/member-function-pointers.cpp
+++ b/clang/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;
+ }
+}
OpenPOWER on IntegriCloud