diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java index e7ddde25205..e24d13be73a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java @@ -2514,5 +2514,23 @@ public class CompleteParseASTTest extends CompleteParseBaseTest } } + public void testBug79810A() throws Exception { + Writer writer = new StringWriter(); + writer.write("void foo() {\n"); //$NON-NLS-1$ + writer.write("int test;\n"); //$NON-NLS-1$ + writer.write("if ((__extension__ ({ union { int __in; int __i; } __u; __u.__in = (test); __u.__i; })) & 0x7f) {}\n}\n"); //$NON-NLS-1$ + parse(writer.toString()); + + writer = new StringWriter(); + writer.write("#define __WTERMSIG(status) ((status) & 0x7f)\n"); //$NON-NLS-1$ + writer.write("#define __WIFEXITED(status) (__WTERMSIG(status) == 0)\n"); //$NON-NLS-1$ + writer.write("#define __WAIT_INT(status) (__extension__ ({ union { int __in; int __i; } __u; \\\n"); //$NON-NLS-1$ + writer.write(" __u.__in = (test); __u.__i; }))\n"); //$NON-NLS-1$ + writer.write("#define WIFEXITED(status) __WIFEXITED(__WAIT_INT(status))\n"); //$NON-NLS-1$ + writer.write("void foo() {\n"); //$NON-NLS-1$ + writer.write("int test;\n"); //$NON-NLS-1$ + writer.write("if (WIFEXITED(test)) {}\n}\n"); //$NON-NLS-1$ + parse(writer.toString()); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java index 911348f1382..337c9437154 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java @@ -222,4 +222,53 @@ public class CompleteParsePluginTest extends FileBasePluginTest { assertEquals(foo.getName(), "foo"); //$NON-NLS-1$ assertTrue(new String(foo.getFilename()).indexOf("header.h") > 0); //$NON-NLS-1$ } + + public void testBug79810B() throws Exception { + Writer writer = new StringWriter(); + writer.write("#define __WTERMSIG(status) ((status) & 0x7f)\n"); //$NON-NLS-1$ + writer.write("#define __WIFEXITED(status) (__WTERMSIG(status) == 0)\n"); //$NON-NLS-1$ + writer.write("#define __WAIT_INT(status) (__extension__ ({ union { int __in; int __i; } __u; \\\n"); //$NON-NLS-1$ + writer.write(" __u.__in = (test); __u.__i; }))\n"); //$NON-NLS-1$ + writer.write("#define WIFEXITED(status) __WIFEXITED(__WAIT_INT(status))\n"); //$NON-NLS-1$ + importFile( "header.h", writer.toString() ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "#include \"header.h\" \n"); //$NON-NLS-1$ + writer.write("void foo() {\n"); //$NON-NLS-1$ + writer.write("int test;\n"); //$NON-NLS-1$ + writer.write("if (WIFEXITED(test)) {}\n}\n"); //$NON-NLS-1$ + IFile cpp = importFile( "test.cpp", writer.toString() ); //$NON-NLS-1$ + + List calls = new ArrayList(); + parse( cpp, calls ); + + Iterator i = calls.iterator(); + + assertEquals( i.next(), CallbackTracker.ENTER_COMPILATION_UNIT ); + assertEquals( i.next(), CallbackTracker.ENTER_INCLUSION ); + assertEquals( i.next(), CallbackTracker.ACCEPT_MACRO ); + assertEquals( i.next(), CallbackTracker.ACCEPT_MACRO ); + assertEquals( i.next(), CallbackTracker.ACCEPT_MACRO ); + assertEquals( i.next(), CallbackTracker.ACCEPT_MACRO ); + assertEquals( i.next(), CallbackTracker.EXIT_INCLUSION ); + assertEquals( i.next(), CallbackTracker.ENTER_FUNCTION ); + assertEquals( i.next(), CallbackTracker.ACCEPT_VARIABLE ); + assertEquals( i.next(), CallbackTracker.ENTER_CODE_BLOCK ); + assertEquals( i.next(), CallbackTracker.ENTER_CLASS_SPEC ); + assertEquals( i.next(), CallbackTracker.ACCEPT_FIELD ); + assertEquals( i.next(), CallbackTracker.ACCEPT_FIELD ); + assertEquals( i.next(), CallbackTracker.EXIT_CLASS ); + assertEquals( i.next(), CallbackTracker.ACCEPT_VARIABLE ); + assertEquals( i.next(), CallbackTracker.ACCEPT_REFERENCE ); + assertEquals( i.next(), CallbackTracker.ACCEPT_REFERENCE ); + assertEquals( i.next(), CallbackTracker.ACCEPT_REFERENCE ); + assertEquals( i.next(), CallbackTracker.ACCEPT_REFERENCE ); + assertEquals( i.next(), CallbackTracker.ACCEPT_REFERENCE ); + assertEquals( i.next(), CallbackTracker.EXIT_CODE_BLOCK ); + assertEquals( i.next(), CallbackTracker.ENTER_CODE_BLOCK ); + assertEquals( i.next(), CallbackTracker.EXIT_CODE_BLOCK ); + assertEquals( i.next(), CallbackTracker.EXIT_FUNCTION ); + assertEquals( i.next(), CallbackTracker.EXIT_COMPILATION_UNIT ); + assertFalse( i.hasNext() ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index 6420fc84aaf..8fe1efc44d0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -1391,6 +1391,21 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto rhs = rhs.getTypeSymbol().getTypeInfo(); } + boolean checkInvalidConversion = true; + IASTExpression expLeftTest = lhsExp.getLHSExpression(); + IASTExpression expRightTest = rhsExp.getLHSExpression(); + while (expLeftTest != null && !(expLeftTest instanceof ASTEmptyExpression)) { + expLeftTest = expLeftTest.getLHSExpression(); + } + + while (expRightTest != null && !(expRightTest instanceof ASTEmptyExpression)) { + expRightTest = expRightTest.getLHSExpression(); + } + + if ((expLeftTest != null && expLeftTest instanceof ASTEmptyExpression) || (expRightTest != null && expRightTest instanceof ASTEmptyExpression)) + checkInvalidConversion = false; + + if (checkInvalidConversion) { // invalid arithmetic detection TODO add support for 4.5 Integral Promotions/4.7 Integral Conversions if necessary // 5.6 Multiplicative Operators: The operands of * and / shall have arithmetic or enumeration type; the operands of % shall have integral or enumeration type. if (kind == IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY || kind == IASTExpression.Kind.MULTIPLICATIVE_DIVIDE) { @@ -1435,7 +1450,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) ) handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); } - + } + ITypeInfo info = TypeInfoProvider.newTypeInfo( ); if( ( lhs.checkBit(ITypeInfo.isLong) && lhs.getType() == ITypeInfo.t_double)