1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Bug 45203. Proper handling of NULL function arguments.

This commit is contained in:
Sergey Prigogin 2013-08-05 16:55:36 -07:00
parent f9aa816e58
commit 3ddf467f4d
4 changed files with 38 additions and 23 deletions

View file

@ -1121,7 +1121,7 @@ public class Conversions {
return false;
}
private static boolean isNullPointerConstant(IType s) {
public static boolean isNullPointerConstant(IType s) {
if (s instanceof CPPBasicType) {
final CPPBasicType basicType = (CPPBasicType) s;
if (basicType.getKind() == Kind.eNullPtr)

View file

@ -192,6 +192,8 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase {
// void test(A* a) {
// f(a);
// f(0);
// f(nullptr);
// }
public void testFunctionCall() throws Exception {
IPreferenceStore preferenceStore = getPreferenceStore();

View file

@ -100,6 +100,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.LookupData;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
@ -178,14 +179,18 @@ public class BindingClassifier {
// sufficient if it matches the actual parameter type.
if (argument instanceof IASTExpression) {
IType argumentType = ((IASTExpression) argument).getExpressionType();
argumentType = getNestedType(argumentType, REF | ALLCVQ);
if (parameterType instanceof IPointerType && argumentType instanceof IPointerType) {
parameterType = getNestedType(((IPointerType) parameterType).getType(), ALLCVQ);
argumentType = getNestedType(((IPointerType) argumentType).getType(), ALLCVQ);
}
if (isSameType(parameterType, argumentType)) {
if (parameterType instanceof IPointerType && Conversions.isNullPointerConstant(argumentType)) {
canBeDeclared = true;
} else {
argumentType = getNestedType(argumentType, REF | ALLCVQ);
if (parameterType instanceof IPointerType && argumentType instanceof IPointerType) {
parameterType = getNestedType(((IPointerType) parameterType).getType(), ALLCVQ);
argumentType = getNestedType(((IPointerType) argumentType).getType(), ALLCVQ);
}
if (isSameType(parameterType, argumentType)) {
canBeDeclared = true;
}
}
}
}
@ -636,7 +641,7 @@ public class BindingClassifier {
}
// Get the arguments of the initializer.
IASTInitializerClause[] arguments = new IASTInitializerClause[] { };
IASTInitializerClause[] arguments = IASTExpression.EMPTY_EXPRESSION_ARRAY;
if (initializer instanceof ICPPASTConstructorInitializer) {
ICPPASTConstructorInitializer constructorInitializer = (ICPPASTConstructorInitializer) initializer;
arguments = constructorInitializer.getArguments();
@ -659,13 +664,13 @@ public class BindingClassifier {
// We're constructing a pointer type. No constructor is called. We however have
// to check whether the argument type matches the declared type.
memberType = getNestedType(memberType, REF);
for (IASTInitializerClause actualParameter : arguments) {
if (actualParameter instanceof IASTExpression) {
IType parameterType = ((IASTExpression) actualParameter).getExpressionType();
if (!isSameType(memberType, parameterType)) {
for (IASTInitializerClause argument : arguments) {
if (argument instanceof IASTExpression) {
IType argumentType = ((IASTExpression) argument).getExpressionType();
if (!Conversions.isNullPointerConstant(argumentType) && !isSameType(memberType, argumentType)) {
// Types don't match. Define both types.
defineTypeExceptTypedefOrNonFixedEnum(memberType);
defineTypeExceptTypedefOrNonFixedEnum(parameterType);
defineTypeExceptTypedefOrNonFixedEnum(argumentType);
}
}
}

View file

@ -17,26 +17,28 @@ public class GCCHeaderSubstitutionMaps {
@SuppressWarnings("nls")
private static final String[] symbolExportMap = new String[] {
"EOF", "<stdio.h>",
"EOF", "<cstdio>",
"EOF", "<libio.h>",
"NULL", "<stddef.h>",
"NULL", "<cstddef>",
"NULL", "<cstdio>",
"NULL", "<cstdlib>",
"NULL", "<cstring>",
"NULL", "<ctime>",
"NULL", "<cwchar>",
"NULL", "<string>",
"NULL", "<locale.h>",
"NULL", "<stdio.h>",
"NULL", "<stdlib.h>",
"NULL", "<cstdlib>",
"NULL", "<stdio.h>",
"NULL", "<cstdio>",
"NULL", "<string.h>",
"NULL", "<time.h>",
"NULL", "<cstring>",
"NULL", "<string>",
"NULL", "<wchar.h>",
"NULL", "<cwchar>",
"NULL", "<locale.h>",
"NULL", "<time.h>",
"NULL", "<ctime>",
"blkcnt_t", "<sys/stat.h>",
"blkcnt_t", "<sys/types.h>",
"blksize_t", "<sys/types.h>",
"blksize_t", "<sys/stat.h>",
"calloc", "<stdlib.h>",
"calloc", "<cstdlib>",
"daddr_t", "<sys/types.h>",
"daddr_t", "<rpc/types.h>",
"dev_t", "<sys/types.h>",
@ -45,6 +47,7 @@ public class GCCHeaderSubstitutionMaps {
"error_t", "<argp.h>",
"error_t", "<argz.h>",
"free", "<stdlib.h>",
"free", "<cstdlib>",
"fsblkcnt_t", "<sys/types.h>",
"fsblkcnt_t", "<sys/statvfs.h>",
"fsfilcnt_t", "<sys/types.h>",
@ -70,6 +73,7 @@ public class GCCHeaderSubstitutionMaps {
"key_t", "<sys/types.h>",
"key_t", "<sys/ipc.h>",
"malloc", "<stdlib.h>",
"malloc", "<cstdlib>",
"mode_t", "<sys/types.h>",
"mode_t", "<sys/stat.h>",
"mode_t", "<sys/ipc.h>",
@ -89,12 +93,15 @@ public class GCCHeaderSubstitutionMaps {
"pid_t", "<sys/shm.h>",
"pid_t", "<termios.h>",
"pid_t", "<time.h>",
"pid_t", "<ctime>",
"pid_t", "<utmpx.h>",
"realloc", "<stdlib.h>",
"realloc", "<cstdlib>",
"sigset_t", "<signal.h>",
"sigset_t", "<sys/epoll.h>",
"sigset_t", "<sys/select.h>",
"size_t", "<stddef.h>",
"size_t", "<cstddef>",
"socklen_t", "<bits/socket.h>",
"socklen_t", "<unistd.h>",
"socklen_t", "<arpa/inet.h>",
@ -125,6 +132,7 @@ public class GCCHeaderSubstitutionMaps {
"useconds_t", "<sys/types.h>",
"useconds_t", "<unistd.h>",
"va_list", "<stdarg.h>",
"va_list", "<cstdarg>",
};
@SuppressWarnings("nls")