示例#1
0
        private ExpressionSyntax GenIncDec(FuzzType type, bool isIncrement)
        {
            SyntaxKind[] acceptedTypes =
            {
                SyntaxKind.ULongKeyword,
                SyntaxKind.LongKeyword,
                SyntaxKind.UIntKeyword,
                SyntaxKind.IntKeyword,
                SyntaxKind.UShortKeyword,
                SyntaxKind.ShortKeyword,
                SyntaxKind.ByteKeyword,
                SyntaxKind.SByteKeyword,
            };

            if (!(type is PrimitiveType pt) || !acceptedTypes.Contains(pt.Keyword))
            {
                return(null);
            }

            LValueInfo subject = GenExistingLValue(type, int.MinValue);

            if (subject == null)
            {
                return(null);
            }

            ExpressionSyntax gen = PostfixUnaryExpression(
                isIncrement ? SyntaxKind.PostIncrementExpression : SyntaxKind.PostDecrementExpression,
                subject.Expression);

            return(gen);
        }
示例#2
0
        /// <summary>Returns an lvalue.</summary>
        private LValueInfo GenLValue(FuzzType type, int minRefEscapeScope)
        {
            Debug.Assert(type != null);

            LValueInfo lv = GenExistingLValue(type, minRefEscapeScope);

            if (lv == null)
            {
                StaticField newStatic = Statics.GenerateNewField(type);
                lv = new LValueInfo(IdentifierName(newStatic.Var.Name), type, int.MaxValue);
            }

            return(lv);
        }
示例#3
0
        private static void AppendVariablePaths(List <LValueInfo> paths, VariableIdentifier var)
        {
            ExpressionSyntax varAccess = IdentifierName(var.Name);

            AddPathsRecursive(varAccess, var.Type, var.RefEscapeScope);

            void AddPathsRecursive(ExpressionSyntax curAccess, FuzzType curType, int curRefEscapeScope)
            {
                LValueInfo info = new LValueInfo(curAccess, curType, curRefEscapeScope);

                paths.Add(info);

                if (curType is RefType rt)
                {
                    curType = rt.InnerType;
                }

                switch (curType)
                {
                case ArrayType arr:
                    AddPathsRecursive(
                        ElementAccessExpression(
                            curAccess,
                            BracketedArgumentList(
                                SeparatedList(
                                    Enumerable.Repeat(
                                        Argument(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0))),
                                        arr.Rank)))),
                        arr.ElementType,
                        curRefEscapeScope: int.MaxValue);
                    break;

                case AggregateType agg:
                    foreach (AggregateField field in agg.Fields)
                    {
                        AddPathsRecursive(
                            MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                curAccess,
                                IdentifierName(field.Name)),
                            field.Type,
                            curRefEscapeScope: agg.IsClass?int.MaxValue: curRefEscapeScope);
                    }
                    break;
                }
            }
        }
示例#4
0
        private ArgumentSyntax[] GenArgs(FuncGenerator funcToCall, int minRefEscapeScope, out int argsMinRefEscapeScope)
        {
            ArgumentSyntax[] args = new ArgumentSyntax[funcToCall.Parameters.Length];
            argsMinRefEscapeScope = int.MaxValue;

            for (int i = 0; i < args.Length; i++)
            {
                FuzzType paramType = funcToCall.Parameters[i].Type;
                if (paramType is RefType rt)
                {
                    LValueInfo lv = GenLValue(rt.InnerType, minRefEscapeScope);
                    argsMinRefEscapeScope = Math.Min(argsMinRefEscapeScope, lv.RefEscapeScope);
                    args[i] = Argument(lv.Expression).WithRefKindKeyword(Token(SyntaxKind.RefKeyword));
                }
                else
                {
                    args[i] = Argument(GenExpression(paramType));
                }
            }

            return(args);
        }
示例#5
0
        private StatementSyntax GenAssignmentStatement()
        {
            LValueInfo lvalue = null;

            if (!Random.FlipCoin(Options.AssignToNewVarProb))
            {
                lvalue = GenExistingLValue(null, int.MinValue);
            }

            if (lvalue == null)
            {
                FuzzType newType = Types.PickType(Options.LocalIsByRefProb);
                // Determine if we should create a new local. We do this with a certain probabilty,
                // or always if the new type is a by-ref type (we cannot have static by-refs).
                if (newType is RefType || Random.FlipCoin(Options.NewVarIsLocalProb))
                {
                    VariableIdentifier variable;
                    string             varName = $"var{_varCounter++}";
                    ExpressionSyntax   rhs;
                    if (newType is RefType newRt)
                    {
                        LValueInfo rhsLV = GenLValue(newRt.InnerType, int.MinValue);
                        variable = new VariableIdentifier(newType, varName, rhsLV.RefEscapeScope);
                        rhs      = RefExpression(rhsLV.Expression);
                    }
                    else
                    {
                        rhs      = GenExpression(newType);
                        variable = new VariableIdentifier(newType, varName, -(_scope.Count - 1));
                    }

                    LocalDeclarationStatementSyntax decl =
                        LocalDeclarationStatement(
                            VariableDeclaration(
                                variable.Type.GenReferenceTo(),
                                SingletonSeparatedList(
                                    VariableDeclarator(variable.Name)
                                    .WithInitializer(
                                        EqualsValueClause(rhs)))));

                    _scope.Last().Variables.Add(variable);

                    return(decl);
                }

                StaticField newStatic = Statics.GenerateNewField(newType);
                lvalue = new LValueInfo(IdentifierName(newStatic.Var.Name), newType, int.MaxValue);
            }

            // Determine if we should generate a ref-reassignment. In that case we cannot do anything
            // clever, like generate compound assignments.
            FuzzType rhsType = lvalue.Type;

            if (lvalue.Type is RefType rt)
            {
                if (Random.FlipCoin(Options.AssignGenRefReassignProb))
                {
                    RefExpressionSyntax refRhs = RefExpression(GenLValue(rt.InnerType, lvalue.RefEscapeScope).Expression);
                    return
                        (ExpressionStatement(
                             AssignmentExpression(
                                 SyntaxKind.SimpleAssignmentExpression,
                                 lvalue.Expression,
                                 refRhs)));
                }

                // We have a ref-type, but are not generating a ref-reassign, so lift the type and make a normal assignment.
                rhsType = rt.InnerType;
            }

            SyntaxKind assignmentKind = SyntaxKind.SimpleAssignmentExpression;

            // Determine if we should generate compound assignment.
            if (rhsType.AllowedAdditionalAssignmentKinds.Length > 0 && Random.FlipCoin(Options.CompoundAssignmentProb))
            {
                assignmentKind = Random.NextElement(rhsType.AllowedAdditionalAssignmentKinds);
            }

            // Early our for simple cases.
            if (assignmentKind == SyntaxKind.PreIncrementExpression ||
                assignmentKind == SyntaxKind.PreDecrementExpression)
            {
                return(ExpressionStatement(PrefixUnaryExpression(assignmentKind, lvalue.Expression)));
            }

            if (assignmentKind == SyntaxKind.PostIncrementExpression ||
                assignmentKind == SyntaxKind.PostDecrementExpression)
            {
                return(ExpressionStatement(PostfixUnaryExpression(assignmentKind, lvalue.Expression)));
            }

            // Right operand of shifts are always ints.
            if (assignmentKind == SyntaxKind.LeftShiftAssignmentExpression ||
                assignmentKind == SyntaxKind.RightShiftAssignmentExpression)
            {
                rhsType = Types.GetPrimitiveType(SyntaxKind.IntKeyword);
            }

            ExpressionSyntax right = GenExpression(rhsType);

            // For modulo and division we don't want to throw divide-by-zero exceptions,
            // so always or right-hand-side with 1.
            if (assignmentKind == SyntaxKind.ModuloAssignmentExpression ||
                assignmentKind == SyntaxKind.DivideAssignmentExpression)
            {
                right =
                    CastExpression(
                        rhsType.GenReferenceTo(),
                        ParenthesizedExpression(
                            BinaryExpression(
                                SyntaxKind.BitwiseOrExpression,
                                ParenthesizeIfNecessary(right),
                                LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(1)))));
            }

            return(ExpressionStatement(AssignmentExpression(assignmentKind, lvalue.Expression, right)));
        }