diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index a298da40e4e..a3c6228f048 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -6352,11 +6352,11 @@ public class AST2CPPTests extends AST2BaseTest {
     //  };
     //
     //  struct B {
-    //    A operator-(B b2);
-    //    A operator+(B& b2);
-    //    A operator*(const B& b2);
-    //    A operator/(B b2) const;
-    //    A operator%(const B& b2) const;
+    //    A operator-(B b);
+    //    A operator+(B& b);
+    //    A operator*(const B& b);
+    //    A operator/(B b) const;
+    //    A operator%(const B& b) const;
     //  };
     //
     //  void test(B p1, B p2) {
@@ -6366,7 +6366,7 @@ public class AST2CPPTests extends AST2BaseTest {
     //    (p1 / p2).a; //4
     //    (p1 % p2).a; //5
     //  }
-    public void testOverloadedBinaryOperator_259927() throws Exception {
+    public void testOverloadedBinaryOperator_259927_1() throws Exception {
         BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
         ba.assertNonProblem("a; //1", 1, ICPPField.class);
         ba.assertNonProblem("a; //2", 1, ICPPField.class);
@@ -6374,6 +6374,36 @@ public class AST2CPPTests extends AST2BaseTest {
         ba.assertNonProblem("a; //4", 1, ICPPField.class);
         ba.assertNonProblem("a; //5", 1, ICPPField.class);
     }
+
+    //  struct A {
+    //    int a;
+    //  };
+    //  struct B {};
+    //  enum E { zero };
+    //
+    //  A operator-(B p1, int p2);
+    //  A operator+(int p1, const B& p2);
+    //  A operator*(E p1, int p2);
+    //  A operator/(int p1, const E& p2);
+    //  A operator%(const B& p1, const B& p2);
+    //
+    //  void test(B b, E e, int i) {
+    //    (b - i).a; //1
+    //    (i + b).a; //2
+    //    (e * i).a; //3
+    //    (i / e).a; //4
+    //    (b % b).a; //5
+    //    (b + i).a; //6
+    //  }
+    public void testOverloadedBinaryOperator_259927_2() throws Exception {
+        BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
+        ba.assertNonProblem("a; //1", 1, ICPPField.class);
+        ba.assertNonProblem("a; //2", 1, ICPPField.class);
+        ba.assertNonProblem("a; //3", 1, ICPPField.class);
+        ba.assertNonProblem("a; //4", 1, ICPPField.class);
+        ba.assertNonProblem("a; //5", 1, ICPPField.class);
+        ba.assertProblem("a; //6", 1);
+    }
     
     // int a,b,c,d ;
     // class X {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
index 08fc2e124ca..4e238e1e034 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
@@ -2480,7 +2480,7 @@ public class CPPSemantics {
 		CPPASTName astName = new CPPASTName();
 		astName.setParent(exp);
 	    astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
-	    LookupData data = null;
+	    LookupData data;
 	    
 	    if (exp instanceof IASTUnaryExpression) {
 	    	astName.setName(OverloadableOperator.STAR.toCharArray());
@@ -2532,8 +2532,41 @@ public class CPPSemantics {
 		}
 		return null;
 	}
-	
-	public static IBinding[] findBindings(IScope scope, String name, boolean qualified) throws DOMException{
+
+    /**
+     * Returns the overloaded operator corresponding to a binary expression, or {@code null}
+     * if no such operator is found. 
+     * @param exp a binary expression
+     * @return the overloaded operator, or {@code null}.
+     */
+    public static ICPPFunction findOverloadedOperator(IASTBinaryExpression exp) {
+        OverloadableOperator operator = OverloadableOperator.fromBinaryExpression(exp);
+        if (operator == null) {
+        	return null;
+        }
+
+		IScope scope = CPPVisitor.getContainingScope(exp);
+		if (scope == null)
+			return null;
+
+		CPPASTName astName = new CPPASTName();
+		astName.setParent(exp);
+	    astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
+	    astName.setName(operator.toCharArray());
+	    LookupData data = new LookupData(astName);
+	    data.functionParameters = new IASTExpression[] { exp.getOperand1(), exp.getOperand2() };
+
+		try {
+		    lookup(data, scope);
+		    IBinding binding = resolveAmbiguities(data, astName);
+		    if (binding instanceof ICPPFunction)
+		    	return (ICPPFunction) binding;
+		} catch (DOMException e) {
+		}
+		return null;
+	}
+
+    public static IBinding[] findBindings(IScope scope, String name, boolean qualified) throws DOMException{
 		return findBindings(scope, name.toCharArray(), qualified, null);
 	}
 
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index cabe31709fc..53c92d60ddd 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -1865,28 +1865,36 @@ public class CPPVisitor extends ASTQueries {
 
 	        // Check for overloaded operator.
 			IType type1 = getExpressionType(binary.getOperand1());
-			while (type1 instanceof ITypedef) {
-				try {
-					type1 = ((ITypedef) type1).getType();
-				} catch (DOMException e) {
-					break;
-				}
+			IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
+			if (ultimateType1 instanceof IProblemBinding) {
+				return type1;
 			}
-		    try {
-				if (type1 instanceof ICPPReferenceType) {
-					type1 = ((ICPPReferenceType) type1).getType();
-				}
-				if (type1 instanceof IQualifierType) {
-					type1 = ((IQualifierType) type1).getType();
-				}
-				if (type1 instanceof ICPPClassType) {
-					ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type1);
-					if (operator != null) {
+			if (ultimateType1 instanceof ICPPClassType) {
+				ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) ultimateType1);
+				if (operator != null) {
+					try {
 						return operator.getType().getReturnType();
+					} catch (DOMException e) {
+						return e.getProblem();
+					}
+				}
+			}
+			IType type2 = getExpressionType(binary.getOperand2());
+			IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
+			if (ultimateType2 instanceof IProblemBinding) {
+				return type2;
+			}
+			if (ultimateType1 instanceof ICPPClassType || ultimateType1 instanceof IEnumeration ||
+					ultimateType2 instanceof ICPPClassType || ultimateType2 instanceof IEnumeration) {
+				// If at least one of the types is user defined, the operator can be overloaded.
+				ICPPFunction operator = CPPSemantics.findOverloadedOperator(binary);
+				if (operator != null) {
+					try {
+						return operator.getType().getReturnType();
+					} catch (DOMException e) {
+						return e.getProblem();
 					}
 				}
-			} catch (DOMException e) {
-				return e.getProblem();
 			}
 	        
 	        final int op = binary.getOperator();
@@ -1903,16 +1911,13 @@ public class CPPVisitor extends ASTQueries {
 	        	basicType.setFromExpression(expression);
 	        	return basicType;
 	        case IASTBinaryExpression.op_plus:
-	        	IType t2 = getExpressionType(binary.getOperand2());
-	        	if (SemanticUtil.getUltimateTypeViaTypedefs(t2) instanceof IPointerType) {
-	        		return t2;
+	        	if (ultimateType2 instanceof IPointerType) {
+	        		return ultimateType2;
 	        	}
 	        	break;
 	        case IASTBinaryExpression.op_minus:
-	        	t2= getExpressionType(binary.getOperand2());
-	        	if (SemanticUtil.getUltimateTypeViaTypedefs(t2) instanceof IPointerType) {
-	        		IType t1 = getExpressionType(binary.getOperand1());
-	        		if (SemanticUtil.getUltimateTypeViaTypedefs(t1) instanceof IPointerType) {
+	        	if (ultimateType2 instanceof IPointerType) {
+	        		if (ultimateType1 instanceof IPointerType) {
 	        			IScope scope = getContainingScope(expression);
 	        			try {
 	        				IBinding[] bs= CPPSemantics.findBindings(scope, PTRDIFF_T, false, expression);
@@ -1929,22 +1934,22 @@ public class CPPVisitor extends ASTQueries {
 	        			basicType.setFromExpression(expression);
 	        			return basicType;
 	        		}
-	        		return t1;
+	        		return ultimateType1;
 	        	}
 	        	break;
 	        case ICPPASTBinaryExpression.op_pmarrow:
 	        case ICPPASTBinaryExpression.op_pmdot:
-	        	IType type = getExpressionType(((IASTBinaryExpression) expression).getOperand2());
-	        	if (type instanceof ICPPPointerToMemberType) {
+	        	if (type2 instanceof ICPPPointerToMemberType) {
 	        		try {
-	        			return ((ICPPPointerToMemberType) type).getType();
+	        			return ((ICPPPointerToMemberType) type2).getType();
 	        		} catch (DOMException e) {
 	        			return e.getProblem();
 	        		}
 	        	} 
-	        	return new ProblemBinding(binary, IProblemBinding.SEMANTIC_INVALID_TYPE, new char[0]); 
+	        	return new ProblemBinding(binary, IProblemBinding.SEMANTIC_INVALID_TYPE,
+	        			expression.getRawSignature().toCharArray()); 
 	        }
-			return getExpressionType(((IASTBinaryExpression) expression).getOperand1());
+			return type1;
 	    } else if (expression instanceof IASTUnaryExpression) {
 	    	final int op= ((IASTUnaryExpression) expression).getOperator();
 			switch (op) {
@@ -1955,21 +1960,14 @@ public class CPPVisitor extends ASTQueries {
 			}
 			
 			IType type = getExpressionType(((IASTUnaryExpression) expression).getOperand());
-			while (type instanceof ITypedef) {
-				try {
-					type = ((ITypedef) type).getType();
-				} catch (DOMException e) {
-					break;
-				}
-			}
+			type = SemanticUtil.getUltimateTypeViaTypedefs(type);
+
 			if (op == IASTUnaryExpression.op_star) {
 			    try {
-					if (type instanceof ICPPReferenceType) {
-						type = ((ICPPReferenceType) type).getType();
-					}
-					if (type instanceof IQualifierType) {
-						type = ((IQualifierType) type).getType();
-					}
+			    	type = SemanticUtil.getUltimateTypeUptoPointers(type);
+			    	if (type instanceof IProblemBinding) {
+			    		return type;
+			    	}
 					if (type instanceof ICPPClassType) {
 						ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type);
 						if (operator != null) {