1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-02 22:05:44 +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; return false;
} }
private static boolean isNullPointerConstant(IType s) { public static boolean isNullPointerConstant(IType s) {
if (s instanceof CPPBasicType) { if (s instanceof CPPBasicType) {
final CPPBasicType basicType = (CPPBasicType) s; final CPPBasicType basicType = (CPPBasicType) s;
if (basicType.getKind() == Kind.eNullPtr) if (basicType.getKind() == Kind.eNullPtr)

View file

@ -192,6 +192,8 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase {
// void test(A* a) { // void test(A* a) {
// f(a); // f(a);
// f(0);
// f(nullptr);
// } // }
public void testFunctionCall() throws Exception { public void testFunctionCall() throws Exception {
IPreferenceStore preferenceStore = getPreferenceStore(); 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.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; 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.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.LookupData;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
@ -178,6 +179,9 @@ public class BindingClassifier {
// sufficient if it matches the actual parameter type. // sufficient if it matches the actual parameter type.
if (argument instanceof IASTExpression) { if (argument instanceof IASTExpression) {
IType argumentType = ((IASTExpression) argument).getExpressionType(); IType argumentType = ((IASTExpression) argument).getExpressionType();
if (parameterType instanceof IPointerType && Conversions.isNullPointerConstant(argumentType)) {
canBeDeclared = true;
} else {
argumentType = getNestedType(argumentType, REF | ALLCVQ); argumentType = getNestedType(argumentType, REF | ALLCVQ);
if (parameterType instanceof IPointerType && argumentType instanceof IPointerType) { if (parameterType instanceof IPointerType && argumentType instanceof IPointerType) {
@ -190,6 +194,7 @@ public class BindingClassifier {
} }
} }
} }
}
if (canBeDeclared) { if (canBeDeclared) {
// The declared parameter type must be declared. We must explicitly do this here // The declared parameter type must be declared. We must explicitly do this here
@ -636,7 +641,7 @@ public class BindingClassifier {
} }
// Get the arguments of the initializer. // Get the arguments of the initializer.
IASTInitializerClause[] arguments = new IASTInitializerClause[] { }; IASTInitializerClause[] arguments = IASTExpression.EMPTY_EXPRESSION_ARRAY;
if (initializer instanceof ICPPASTConstructorInitializer) { if (initializer instanceof ICPPASTConstructorInitializer) {
ICPPASTConstructorInitializer constructorInitializer = (ICPPASTConstructorInitializer) initializer; ICPPASTConstructorInitializer constructorInitializer = (ICPPASTConstructorInitializer) initializer;
arguments = constructorInitializer.getArguments(); arguments = constructorInitializer.getArguments();
@ -659,13 +664,13 @@ public class BindingClassifier {
// We're constructing a pointer type. No constructor is called. We however have // We're constructing a pointer type. No constructor is called. We however have
// to check whether the argument type matches the declared type. // to check whether the argument type matches the declared type.
memberType = getNestedType(memberType, REF); memberType = getNestedType(memberType, REF);
for (IASTInitializerClause actualParameter : arguments) { for (IASTInitializerClause argument : arguments) {
if (actualParameter instanceof IASTExpression) { if (argument instanceof IASTExpression) {
IType parameterType = ((IASTExpression) actualParameter).getExpressionType(); IType argumentType = ((IASTExpression) argument).getExpressionType();
if (!isSameType(memberType, parameterType)) { if (!Conversions.isNullPointerConstant(argumentType) && !isSameType(memberType, argumentType)) {
// Types don't match. Define both types. // Types don't match. Define both types.
defineTypeExceptTypedefOrNonFixedEnum(memberType); defineTypeExceptTypedefOrNonFixedEnum(memberType);
defineTypeExceptTypedefOrNonFixedEnum(parameterType); defineTypeExceptTypedefOrNonFixedEnum(argumentType);
} }
} }
} }

View file

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