mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-02 13:55:39 +02:00
Bug 45203. Proper handling of NULL function arguments.
This commit is contained in:
parent
f9aa816e58
commit
3ddf467f4d
4 changed files with 38 additions and 23 deletions
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Add table
Reference in a new issue