Created
September 22, 2021 17:23
-
-
Save UplinkCoder/f58bb154d560fa0d1917562e98824bf4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import core.reflect.reflect; | |
| import core.reflect.transitiveVisitor; | |
| int f() | |
| { | |
| int x; | |
| g(&x); | |
| return x; | |
| // yes unfortunately for now this is where the static assert has to be :-( | |
| // that resolution bug will be fixed at some point. | |
| pragma(msg, isAliased( | |
| nodeFromName("x", ReflectFlags.NoParentRecursion | ReflectFlags.NoFunctionbodyRecursion | ReflectFlags.NoMemberRecursion) | |
| )); | |
| // output is: MaybeYes. | |
| } | |
| void g(int* x) {} | |
| struct Maybe | |
| { | |
| enum State | |
| { | |
| No, | |
| Yes, | |
| MaybeYes, | |
| MaybeNo, | |
| } | |
| State state; | |
| bool isTrue() | |
| { | |
| return state == state.Yes; | |
| } | |
| bool isFalse() | |
| { | |
| return state == state.No; | |
| } | |
| bool maybeTrue() | |
| { | |
| return state == state.MaybeYes || state == state.Yes; | |
| } | |
| bool maybeFalse() | |
| { | |
| return state == state.MaybeYes || state == state.Yes; | |
| } | |
| } | |
| auto isAliased(const Node var) | |
| { | |
| auto V = cast(const VariableDeclaration) var; | |
| auto F = cast(const FunctionDeclaration) V.parent; | |
| assert(F && V); | |
| class IsAliasedVisitor : TransitiveVisitor | |
| { | |
| Maybe result = Maybe(Maybe.State.No); | |
| alias visit = TransitiveVisitor.visit; | |
| override void visit(SymbolOffsetExpression e) | |
| { | |
| // if anyone takes the address of this we assume it might be aliased; | |
| if (!e.var) return ; | |
| if (auto v = cast(VariableDeclaration)e.var) | |
| { | |
| if (v is V) | |
| { | |
| result = Maybe(result.state.MaybeYes); | |
| return ; | |
| } | |
| } | |
| } | |
| override void visit(AddressOfExpression e) | |
| { | |
| // if anyone takes the address of this we assume it might be aliased; | |
| if (auto v = cast(VariableExpression)e.exp) | |
| { | |
| if (v.var is V) | |
| { | |
| result = Maybe(result.state.MaybeYes); | |
| return ; | |
| } | |
| } | |
| } | |
| } | |
| assert(F.fbody); | |
| scope isAliasedV = new IsAliasedVisitor(); | |
| (cast()F.fbody).accept(isAliasedV); | |
| return isAliasedV.result; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment