Add more sanity checks for dynamic attributes.
authorMarek Safar <marek.safar@gmail.com>
Fri, 6 Aug 2010 16:14:14 +0000 (17:14 +0100)
committerMarek Safar <marek.safar@gmail.com>
Fri, 6 Aug 2010 18:28:10 +0000 (19:28 +0100)
18 files changed:
mcs/errors/cs0121-12.cs [new file with mode: 0644]
mcs/errors/cs0121-8.cs
mcs/errors/cs0182-11.cs [new file with mode: 0644]
mcs/errors/cs0617-2.cs
mcs/errors/cs0617-4.cs [new file with mode: 0644]
mcs/errors/cs0617-5.cs [new file with mode: 0644]
mcs/errors/cs0617.cs
mcs/errors/dcs0182.cs [deleted file]
mcs/errors/dcs1982-2.cs [new file with mode: 0644]
mcs/errors/dcs1982-3.cs [new file with mode: 0644]
mcs/errors/dcs1982-4.cs [new file with mode: 0644]
mcs/errors/dcs1982-5.cs [new file with mode: 0644]
mcs/errors/dcs1982.cs [new file with mode: 0644]
mcs/mcs/attribute.cs
mcs/mcs/constant.cs
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/report.cs

diff --git a/mcs/errors/cs0121-12.cs b/mcs/errors/cs0121-12.cs
new file mode 100644 (file)
index 0000000..27ac112
--- /dev/null
@@ -0,0 +1,18 @@
+// CS0121: The call is ambiguous between the following methods or properties: `D.Test(bool, string)' and `D.Test(bool, int, string)'
+// Line: 16
+
+public class D
+{
+       static void Test (bool b, string a = "s")
+       {
+       }
+
+       static void Test (bool b, int i = 9, string a = "b")
+       {
+       }
+
+       public static void Main ()
+       {
+               Test (false);
+       }
+}
index 75403fc34259a9f9ba0d1138a0493e6e2eda75a5..776941a35ff4066fb2c7dfb3149145053fb45ae0 100644 (file)
@@ -1,6 +1,5 @@
 // CS0121: The call is ambiguous between the following methods or properties: `C.Foo(byte)' and `C.Foo(int)'
 // Line: 18
-// Compiler options: -langversion:future
 
 class C
 {
diff --git a/mcs/errors/cs0182-11.cs b/mcs/errors/cs0182-11.cs
new file mode 100644 (file)
index 0000000..e717b64
--- /dev/null
@@ -0,0 +1,16 @@
+// CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression
+// Line: 13
+
+using System;
+
+class MyAttribute : Attribute
+{
+       public MyAttribute (object s)
+       {
+       }
+}
+
+[My (decimal.MaxValue)]
+class X
+{
+}
index 0fc21238475d550e7beb2f912680847e05064f45..a029d4168452d97169467cc18d8a533c642b3864 100644 (file)
@@ -1,4 +1,4 @@
-// cs0617-2.cs: `foo3' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, const or read-write properties which are public and not static
+// CS0617: `foo3' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, const or read-write properties which are public and not static
 // Line: 11
 
 class BazAttribute : System.Attribute 
diff --git a/mcs/errors/cs0617-4.cs b/mcs/errors/cs0617-4.cs
new file mode 100644 (file)
index 0000000..4f94f3b
--- /dev/null
@@ -0,0 +1,14 @@
+// CS0617: `Foo' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, const or read-write properties which are public and not static
+// Line: 11
+
+using System;
+
+public sealed class FooAttribute : Attribute
+{
+       internal int Foo;
+}
+
+[Foo (Foo = 1)]
+public class Tests
+{
+}
diff --git a/mcs/errors/cs0617-5.cs b/mcs/errors/cs0617-5.cs
new file mode 100644 (file)
index 0000000..e9a49b2
--- /dev/null
@@ -0,0 +1,14 @@
+// CS0617: `Foo' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, const or read-write properties which are public and not static
+// Line: 11
+
+using System;
+
+public sealed class FooAttribute : Attribute
+{
+       public short Foo { get; private set; }
+}
+
+[Foo (Foo = 1)]
+public class Tests
+{
+}
index 04a97a9f2a36b933becb2ce19c64e7077260f0bc..b8d8ab726ed53c008998c80c4cfa361f549ca857 100644 (file)
@@ -1,26 +1,25 @@
-// cs0617.cs: `MyNamedArg' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, const or read-write properties which are public and not static
-// Line : 20
+// CS0617: `MyNamedArg' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, const or read-write properties which are public and not static
+// Line : 19
 
 using System;
 
 [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
-       public class SimpleAttribute : Attribute {
+public class SimpleAttribute : Attribute
+{
+       string name;
 
-               string name = null;
-
-               public readonly string MyNamedArg;
-               
-               public SimpleAttribute (string name)
-               {
-                       this.name = name;
-               }
+       public readonly string MyNamedArg;
 
+       public SimpleAttribute (string name)
+       {
+               this.name = name;
        }
+}
 
 [Simple ("Dummy", MyNamedArg = "Dude!")]
-       public class Blah {
+public class Blah {
 
-               public static void Main ()
-               {
-               }
+       public static void Main ()
+       {
        }
+}
diff --git a/mcs/errors/dcs0182.cs b/mcs/errors/dcs0182.cs
deleted file mode 100644 (file)
index cbaafd0..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression
-// Line: 13
-
-using System;
-
-class AAttribute : Attribute
-{
-       public AAttribute (dynamic X)
-       {
-       }
-}
-
-[A (Test.B)]
-class Test
-{
-       public static dynamic B;
-
-       static void Main ()
-       {
-       }
-}
diff --git a/mcs/errors/dcs1982-2.cs b/mcs/errors/dcs1982-2.cs
new file mode 100644 (file)
index 0000000..bbd7e16
--- /dev/null
@@ -0,0 +1,12 @@
+// CS01982: An attribute argument cannot be dynamic expression
+// Line: 6
+
+using System;
+
+[A((dynamic) null)]
+public class A : Attribute
+{
+       public A (Type arg)
+       {
+       }
+}
diff --git a/mcs/errors/dcs1982-3.cs b/mcs/errors/dcs1982-3.cs
new file mode 100644 (file)
index 0000000..7af87df
--- /dev/null
@@ -0,0 +1,12 @@
+// CS01982: An attribute argument cannot be dynamic expression
+// Line: 6
+
+using System;
+
+[A(typeof (dynamic[]))]
+public class A : Attribute
+{
+       public A (object arg)
+       {
+       }
+}
diff --git a/mcs/errors/dcs1982-4.cs b/mcs/errors/dcs1982-4.cs
new file mode 100644 (file)
index 0000000..8d3728e
--- /dev/null
@@ -0,0 +1,12 @@
+// CS01982: An attribute argument cannot be dynamic expression
+// Line: 6
+
+using System;
+
+[A(new dynamic [] { 8 })]
+public class A : Attribute
+{
+       public A (object arg)
+       {
+       }
+}
diff --git a/mcs/errors/dcs1982-5.cs b/mcs/errors/dcs1982-5.cs
new file mode 100644 (file)
index 0000000..58ea1c6
--- /dev/null
@@ -0,0 +1,12 @@
+// CS01982: An attribute argument cannot be dynamic expression
+// Line: 6
+
+using System;
+
+[A(typeof (Func<dynamic>))]
+public class A : Attribute
+{
+       public A (Type arg)
+       {
+       }
+}
diff --git a/mcs/errors/dcs1982.cs b/mcs/errors/dcs1982.cs
new file mode 100644 (file)
index 0000000..344638f
--- /dev/null
@@ -0,0 +1,21 @@
+// CS1982: An attribute argument cannot be dynamic expression
+// Line: 13
+
+using System;
+
+class AAttribute : Attribute
+{
+       public AAttribute (dynamic X)
+       {
+       }
+}
+
+[A (Test.B)]
+class Test
+{
+       public static dynamic B;
+
+       static void Main ()
+       {
+       }
+}
index c6d7aa44e3704b35c523c21e2cc272eec90a4370..288ecd6b526d37046152b591f13fb78d569b81f4 100644 (file)
@@ -178,11 +178,9 @@ namespace Mono.CSharp {
                                name.Name);
                }
 
-               public static void Error_AttributeArgumentNotValid (IMemberContext rc, Location loc)
+               public static void Error_AttributeArgumentIsDynamic (IMemberContext context, Location loc)
                {
-                       rc.Compiler.Report.Error (182, loc,
-                                     "An attribute argument must be a constant expression, typeof " +
-                                     "expression or array creation expression");
+                       context.Compiler.Report.Error (1982, loc, "An attribute argument cannot be dynamic expression");
                }
                
                public void Error_MissingGuidAttribute ()
@@ -419,7 +417,7 @@ namespace Mono.CSharp {
                                bool dynamic;
                                PosArguments.Resolve (ec, out dynamic);
                                if (dynamic) {
-                                       Error_AttributeArgumentNotValid (ec, loc);
+                                       Error_AttributeArgumentIsDynamic (ec.MemberContext, loc);
                                        return null;
                                }
                        }
@@ -472,7 +470,7 @@ namespace Mono.CSharp {
                                if (member is PropertyExpr) {
                                        var pi = ((PropertyExpr) member).PropertyInfo;
 
-                                       if (!pi.HasSet || !pi.HasGet || pi.IsStatic) {
+                                       if (!pi.HasSet || !pi.HasGet || pi.IsStatic || !pi.Get.IsPublic || !pi.Set.IsPublic) {
                                                ec.Report.SymbolRelatedToPreviousError (pi);
                                                Error_InvalidNamedArgument (ec, a);
                                                return false;
@@ -488,7 +486,7 @@ namespace Mono.CSharp {
                                } else {
                                        var fi = ((FieldExpr) member).Spec;
 
-                                       if (fi.IsReadOnly || fi.IsStatic) {
+                                       if (fi.IsReadOnly || fi.IsStatic || !fi.IsPublic) {
                                                Error_InvalidNamedArgument (ec, a);
                                                return false;
                                        }
@@ -1064,11 +1062,6 @@ namespace Mono.CSharp {
                                var param_types = ctor.Parameters.Types;
                                for (int j = 0; j < PosArguments.Count; ++j) {
                                        var pt = param_types[j];
-                                       if (!IsValidArgumentType (pt)) {
-                                               Error_AttributeArgumentNotValid (context, loc);
-                                               return;
-                                       }
-
                                        var arg_expr = PosArguments[j].Expr;
                                        if (j == 0) {
                                                if (Type == predefined.IndexerName || Type == predefined.Conditional) {
@@ -1401,6 +1394,14 @@ namespace Mono.CSharp {
 
        public struct AttributeEncoder
        {
+               [Flags]
+               public enum EncodedTypeProperties
+               {
+                       None = 0,
+                       DynamicType = 1,
+                       TypeParameter = 1 << 1
+               }
+
                public readonly BinaryWriter Stream;
 
                public AttributeEncoder (bool empty)
@@ -1425,7 +1426,7 @@ namespace Mono.CSharp {
                        Stream.Write (buf);
                }
 
-               public void Encode (TypeSpec type)
+               public EncodedTypeProperties Encode (TypeSpec type)
                {
                        if (type == TypeManager.bool_type) {
                                Stream.Write ((byte) 0x02);
@@ -1462,10 +1463,13 @@ namespace Mono.CSharp {
                                EncodeTypeName (type);
                        } else if (type.IsArray) {
                                Stream.Write ((byte) 0x1D);
-                               Encode (TypeManager.GetElementType (type));
-                       } else {
-                               throw new NotImplementedException (type.ToString ());
+                               return Encode (TypeManager.GetElementType (type));
+                       } else if (type == InternalType.Dynamic) {
+                               Stream.Write ((byte) 0x51);
+                               return EncodedTypeProperties.DynamicType;
                        }
+
+                       return EncodedTypeProperties.None;
                }
 
                public void EncodeTypeName (TypeSpec type)
index 52c76c4190176a1beba74aec1d8a2f0a32ac12da..bf5062e741a0c66df1e229da36e3f18d6d45d320 100644 (file)
@@ -1980,7 +1980,7 @@ namespace Mono.CSharp {
 
                        var ac = targetType as ArrayContainer;
                        if (ac != null) {
-                               if (ac.Rank != 1)
+                               if (ac.Rank != 1 || ac.Element.IsArray)
                                        base.EncodeAttributeValue (rc, enc, targetType);
                                else
                                        enc.Stream.Write (uint.MaxValue);
index 9e33c9e79ae48c30300f746274615ede6a60a0d9..bb9047a1d487623bdabfdd6929b14f08d759dc15 100644 (file)
@@ -497,7 +497,8 @@ namespace Mono.CSharp {
 
                public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       Attribute.Error_AttributeArgumentNotValid (rc, loc);
+                       rc.Compiler.Report.Error (182, loc,
+                               "An attribute argument must be a constant expression, typeof expression or array creation expression");
                }
 
                /// <summary>
index aeb1cba6d78b1c02e837a5de155ea8a63a968c25..e48e53540e62e94aca03047828f42905243536e9 100644 (file)
@@ -6278,7 +6278,10 @@ namespace Mono.CSharp {
                                        return;
                                }
 
-                               enc.Encode (type);
+                               if (enc.Encode (type) == AttributeEncoder.EncodedTypeProperties.DynamicType) {
+                                       Attribute.Error_AttributeArgumentIsDynamic (rc, loc);
+                                       return;
+                               }
                        }
 
                        // Single dimensional array of 0 size
@@ -6806,6 +6809,24 @@ namespace Mono.CSharp {
                        return this;
                }
 
+               static bool ContainsDynamicType (TypeSpec type)
+               {
+                       if (type == InternalType.Dynamic)
+                               return true;
+
+                       var element_container = type as ElementTypeSpec;
+                       if (element_container != null)
+                               return ContainsDynamicType (element_container.Element);
+
+                       foreach (var t in type.TypeArguments) {
+                               if (ContainsDynamicType (t)) {
+                                       return true;
+                               }
+                       }
+
+                       return false;
+               }
+
                static bool ContainsTypeParameter (TypeSpec type)
                {
                        if (type.Kind == MemberKind.TypeParameter)
@@ -6833,7 +6854,12 @@ namespace Mono.CSharp {
 
                        if (ContainsTypeParameter (typearg)) {
                                rc.Compiler.Report.Error (416, loc, "`{0}': an attribute argument cannot use type parameters",
-                                       TypeManager.CSharpName (typearg));
+                                       typearg.GetSignatureForError ());
+                               return;
+                       }
+
+                       if (ContainsDynamicType (typearg)) {
+                               Attribute.Error_AttributeArgumentIsDynamic (rc, loc);
                                return;
                        }
 
index 2c5111b9337529da30bbb56cd4f3e18372addc17..b85b4a95657cc54dc23a00b9034d11da6f8be179 100644 (file)
@@ -192,7 +192,7 @@ namespace Mono.CSharp {
 
                        if (mc != null) {
                                SymbolRelatedToPreviousError (mc);
-                       } else {
+                       } else if (ms.MemberDefinition != null) {
                                SymbolRelatedToPreviousError (ms.MemberDefinition.Assembly.Location, "");
                        }
                }