Merge pull request #4318 from tamasvajk/feature/pointer-cast

C#: Add implicit cast from array to pointer
This commit is contained in:
Tamás Vajk
2020-09-28 09:34:54 +02:00
committed by GitHub
14 changed files with 78 additions and 14 deletions

View File

@@ -86,6 +86,15 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
return new ImplicitCast(info);
}
if (conversion.IsIdentity && conversion.IsImplicit &&
convertedType.Symbol is IPointerTypeSymbol &&
!(resolvedType.Symbol is IPointerTypeSymbol))
{
// int[] -> int*
// string -> char*
return new ImplicitCast(info);
}
// Default: Just create the expression without a conversion.
return Factory.Create(info);
}

View File

@@ -762,7 +762,8 @@ pointers.cs:
# 5| 1: [LocalVariableAccess] access to local variable length
# 6| 1: [FixedStmt] fixed(...) { ... }
# 6| -1: [LocalVariableDeclAndInitExpr] Int32* b = ...
# 6| 0: [ParameterAccess] access to parameter arr
# 6| 0: [CastExpr] (...) ...
# 6| 0: [ParameterAccess] access to parameter arr
# 6| 1: [LocalVariableAccess] access to local variable b
# 7| 0: [BlockStmt] {...}
# 8| 0: [LocalVariableDeclStmt] ... ...;

View File

@@ -1327,8 +1327,8 @@ pointers.cs:
# 6| r6_1(glval<Int32*>) = VariableAddress[b] :
# 6| r6_2(glval<Int32[]>) = VariableAddress[arr] :
# 6| r6_3(Int32[]) = Load : &:r6_2, ~m?
# 6| r6_4(Int32*) = Convert : r6_3
# 6| mu6_5(Int32*) = Store : &:r6_1, r6_3
# 6| r6_4(Int32*) = CheckedConvertOrThrow : r6_3
# 6| mu6_5(Int32*) = Store : &:r6_1, r6_4
# 8| r8_1(glval<Int32*>) = VariableAddress[p] :
# 8| r8_2(glval<Int32*>) = VariableAddress[b] :
# 8| r8_3(Int32*) = Load : &:r8_2, ~m?

View File

@@ -725,7 +725,7 @@
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | ... is ... | 14 |
| TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:25:7:25 | ; | 1 |
| TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | exit M | 4 |
| VarDecls.cs:5:18:5:19 | enter M1 | VarDecls.cs:5:18:5:19 | exit M1 | 16 |
| VarDecls.cs:5:18:5:19 | enter M1 | VarDecls.cs:5:18:5:19 | exit M1 | 18 |
| VarDecls.cs:13:12:13:13 | enter M2 | VarDecls.cs:13:12:13:13 | exit M2 | 12 |
| VarDecls.cs:19:7:19:8 | enter M3 | VarDecls.cs:25:20:25:20 | access to parameter b | 12 |
| VarDecls.cs:25:13:25:29 | return ...; | VarDecls.cs:19:7:19:8 | exit M3 | 2 |

View File

@@ -2568,11 +2568,13 @@ dominance
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:7:27:7:33 | access to parameter strings |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:7:35:7:35 | 0 |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:22:7:36 | Char* c1 = ... |
| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:7:22:7:36 | Char* c1 = ... |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:27:7:36 | (...) ... |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:7:27:7:36 | access to array element |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:8:9:10:9 | {...} |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:7:52:7:52 | 1 |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:39:7:53 | Char* c2 = ... |
| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:7:39:7:53 | Char* c2 = ... |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:44:7:53 | (...) ... |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:7:44:7:53 | access to array element |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:9:27:9:28 | access to local variable c1 |
| VarDecls.cs:9:13:9:29 | return ...; | VarDecls.cs:5:18:5:19 | exit M1 |
@@ -5703,12 +5705,14 @@ postDominance
| VarDecls.cs:5:18:5:19 | exit M1 | VarDecls.cs:9:13:9:29 | return ...; |
| VarDecls.cs:6:5:11:5 | {...} | VarDecls.cs:5:18:5:19 | enter M1 |
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:6:5:11:5 | {...} |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:27:7:36 | access to array element |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:27:7:36 | (...) ... |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:7:9:10:9 | fixed(...) { ... } |
| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:7:27:7:36 | access to array element |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:35:7:35 | 0 |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:7:27:7:33 | access to parameter strings |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:7:44:7:53 | access to array element |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:7:44:7:53 | (...) ... |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:7:22:7:36 | Char* c1 = ... |
| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:7:44:7:53 | access to array element |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:52:7:52 | 1 |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:7:39:7:53 | Char* c2 = ... |

View File

@@ -2931,10 +2931,12 @@ nodeEnclosing
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:5:18:5:19 | M1 |

View File

@@ -2064,10 +2064,12 @@
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:7:9:10:9 | fixed(...) { ... } |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:27:7:33 | access to parameter strings |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:7:27:7:33 | access to parameter strings |
| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:7:27:7:33 | access to parameter strings |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:27:7:33 | access to parameter strings |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:7:35:7:35 | 0 |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:7:52:7:52 | 1 |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:8:9:10:9 | {...} |

View File

@@ -2770,10 +2770,12 @@
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:9:13:9:29 | return ...; | return |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:22:7:36 | Char* c1 = ... | normal |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:7:27:7:33 | access to parameter strings | normal |
| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:7:27:7:36 | (...) ... | normal |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:27:7:36 | access to array element | normal |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:7:35:7:35 | 0 | normal |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:7:39:7:53 | Char* c2 = ... | normal |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:7:44:7:50 | access to parameter strings | normal |
| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:7:44:7:53 | (...) ... | normal |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:44:7:53 | access to array element | normal |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:7:52:7:52 | 1 | normal |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:9:13:9:29 | return ...; | return |

View File

@@ -2937,11 +2937,13 @@
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:7:27:7:33 | access to parameter strings | semmle.label | successor |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:44:7:50 | access to parameter strings | semmle.label | successor |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:7:35:7:35 | 0 | semmle.label | successor |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:22:7:36 | Char* c1 = ... | semmle.label | successor |
| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:7:22:7:36 | Char* c1 = ... | semmle.label | successor |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:27:7:36 | (...) ... | semmle.label | successor |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:7:27:7:36 | access to array element | semmle.label | successor |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:8:9:10:9 | {...} | semmle.label | successor |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:7:52:7:52 | 1 | semmle.label | successor |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:39:7:53 | Char* c2 = ... | semmle.label | successor |
| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:7:39:7:53 | Char* c2 = ... | semmle.label | successor |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:44:7:53 | (...) ... | semmle.label | successor |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:7:44:7:53 | access to array element | semmle.label | successor |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:9:27:9:28 | access to local variable c1 | semmle.label | successor |
| VarDecls.cs:9:13:9:29 | return ...; | VarDecls.cs:5:18:5:19 | exit M1 | semmle.label | return |

View File

@@ -0,0 +1,28 @@
using System;
class C
{
unsafe static void M1(int[] arr)
{
fixed (int* i1 = arr)
{
}
fixed (int* i2 = &arr[0])
{
int* i3 = i2;
i3 = i3 + 1;
*i2 = *i2 + 1;
void* v2 = i2;
}
int* i4 = null;
int number = 1024;
byte* p = (byte*)&number;
var s = "some string";
fixed (char* c1 = s)
{ }
}
}

View File

@@ -0,0 +1,11 @@
| Pointer.cs:7:21:7:28 | Pointer.cs:7:21:7:28 | Int32* | Int32* | (...) ... |
| Pointer.cs:11:21:11:32 | Pointer.cs:11:21:11:32 | Int32* | Int32* | &... |
| Pointer.cs:13:18:13:24 | Pointer.cs:13:18:13:24 | Int32* | Int32* | access to local variable i2 |
| Pointer.cs:14:13:14:23 | Pointer.cs:14:13:14:23 | Int32* | Int32* | ... + ... |
| Pointer.cs:15:13:15:25 | Pointer.cs:15:13:15:25 | Int32 | Int32 | ... + ... |
| Pointer.cs:16:19:16:25 | Pointer.cs:16:19:16:25 | Void* | Void* | (...) ... |
| Pointer.cs:19:14:19:22 | Pointer.cs:19:14:19:22 | Int32* | null | null |
| Pointer.cs:21:13:21:25 | Pointer.cs:21:13:21:25 | Int32 | Int32 | 1024 |
| Pointer.cs:22:15:22:32 | Pointer.cs:22:15:22:32 | Byte* | Byte* | (...) ... |
| Pointer.cs:24:13:24:29 | Pointer.cs:24:13:24:29 | String | String | "some string" |
| Pointer.cs:25:22:25:27 | Pointer.cs:25:22:25:27 | Char* | Char* | (...) ... |

View File

@@ -0,0 +1,5 @@
import csharp
from Assignment a
select a.getLocation(), a.getLValue().getType().toString(), a.getRValue().getType().toString(),
a.getRValue().toString()

View File

@@ -1,4 +1 @@
| SignAnalysis.cs:428:23:428:24 | access to constant A |
| SignAnalysis.cs:448:22:448:29 | Byte* to = ... |
| SignAnalysis.cs:450:38:450:44 | (...) ... |
| SignAnalysis.cs:450:43:450:44 | access to local variable to |

View File

@@ -109,7 +109,8 @@ unsafe.cs:
# 36| 1: [LocalVariableAccess] access to local variable data
# 37| 1: [FixedStmt] fixed(...) { ... }
# 37| -1: [LocalVariableDeclAndInitExpr] Int32* p = ...
# 37| 0: [LocalVariableAccess] access to local variable data
# 37| 0: [CastExpr] (...) ...
# 37| 0: [LocalVariableAccess] access to local variable data
# 37| 1: [LocalVariableAccess] access to local variable p
# 38| 0: [BlockStmt] {...}
# 44| 2: [Class] SafeClass