This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Additional features for -fms-extensions


Hi!

I am submitting six patches. They address some problems a company had while porting their sourcecode to GNU/Linux. Until now they compiled their code with the microsoft c++ compiler. When doing this with GCC there were some errors the microsoft compiler didn't complain about. So they tried the -fms-extensions but this did not address all of the problems so they asked me to add some features to the -fms-extensions.

I know that the behavior of the GCC is as it is expected. But I think it is a benefit for the GCC if it CAN do these things as the microsoft compiler can. So I'd be delighted if these patches I submit could be taken into the sources.
I tested those patches on a i686 on a SuSE System and they where tested by the above mentioned company (Fabasoft) with their sources and everything worked fine.

The prblems addressed are: (each with a short description and an example)

+ An ellipsis does not take variables of non-POD type as arguments:
====================================
/*
  Results:

  GCC:
    test2.cxx: In function 'int main()':
    test2.cxx:xx: warning: cannot pass objects of non-POD type 'Class Point'
       through '...'; call will abort at runtime
*/

void test(...)
{
}

class Point
{
public:
  Point(int x, int y) { this->x = x; this->y = y; }
  int getX() { return x; }
  int getY() { return y; }

private:
  int x;
  int y;
};

int main()
{
  Point p(1,1);

  test(p);

  return 0;
}
====================================
+ When passing a lvalue to a function which wants to take a reference there is an error thrown:
====================================
/*
  Results:

  GCC:
    test2.cxx: In function 'int main()':
    test2.cxx:xx: error: no matching function for call to 'Class2::add(Class1)'
    test2.cxx:xx: error: candidates are: static void Class2::add(Class1&)
*/

class A
{
public:
  A() {}
};

class B
{
public:
  static void test(A& a) {}
};


int main()
{
  B::test(A());

  return 0;
}
====================================
+ When declaring a not-anonymous union within an anonymous union an error is thrown
====================================
/*
  Results:

  GCC:
    test3.cxx:xx: error: Union 'TestStruct::<anonymous union>::TestUnion'
    invalid; an anonymous union can only have non-static data members
*/

struct TestStruct
{
  union
  {
    union TestUnion
    {
      int test;
    };
  };
};

int main()
{
  return 0;
}
====================================
+ When declaring something extern and later static an error is thrown
====================================
/*
  Results:

  GCC:
    test4.cxx:xx: error: 'void test()' was declared 'extern' and later 'static'
*/GCC (3.3):

class A
{
  friend void test();
};

static void test()
{
}

int main()
{
  test();
  return 0;
}
====================================
+ There can't be a forward declaration of an enum
====================================
/*
  Results:

  GCC:
    test5.cxx:xx: error: use of enum 'A' without previous declaration
*/

enum A;

int main()
{
  return 0;
}
====================================
+ The address of a member of a packed struct can't be retrieved
====================================
/*
  Results:

  GCC (3.4.2):
    test8.cxx:xx: error: cannot bind packed field `a.A::field2' to `int&'

*/

#include <unistd.h>

struct A
{
  char field1;
  int field2;
} __attribute__((packed));

void test(int& value) 
{
}

int main()
{
  A a;

  test(a.field2);

  return 0;
}
====================================


Index: ./gcc/gcc/cp/call.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.517
diff -c -3 -p -r1.517 call.c
*** ./gcc/gcc/cp/call.c	28 Oct 2004 05:17:08 -0000	1.517
--- ./gcc/gcc/cp/call.c	30 Oct 2004 15:52:23 -0000
*************** convert_arg_to_ellipsis (tree arg)
*** 4394,4400 ****
    arg = require_complete_type (arg);
    
    if (arg != error_mark_node
!       && !pod_type_p (TREE_TYPE (arg)))
      {
        /* Undefined behavior [expr.call] 5.2.2/7.  We used to just warn
  	 here and do a bitwise copy, but now cp_expr_size will abort if we
--- 4396,4403 ----
    arg = require_complete_type (arg);
    
    if (arg != error_mark_node
!       && !pod_type_p (TREE_TYPE (arg))
!       && !flag_ms_extensions)
      {
        /* Undefined behavior [expr.call] 5.2.2/7.  We used to just warn
  	 here and do a bitwise copy, but now cp_expr_size will abort if we
*************** build_x_va_arg (tree expr, tree type)
*** 4426,4432 ****
    if (expr == error_mark_node || !type)
      return error_mark_node;
    
!   if (! pod_type_p (type))
      {
        /* Undefined behavior [expr.call] 5.2.2/7.  */
        warning ("cannot receive objects of non-POD type %q#T' through %<...%>; "
--- 4429,4435 ----
    if (expr == error_mark_node || !type)
      return error_mark_node;
    
!   if (! pod_type_p (type) && ! flag_ms_extensions)
      {
        /* Undefined behavior [expr.call] 5.2.2/7.  */
        warning ("cannot receive objects of non-POD type %q#T' through %<...%>; "
Index: ./gcc/gcc/cp/call.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.517
diff -c -3 -p -r1.517 call.c
*** ./gcc/gcc/cp/call.c	28 Oct 2004 05:17:08 -0000	1.517
--- ./gcc/gcc/cp/call.c	30 Oct 2004 15:52:23 -0000
*************** convert_like_real (conversion *convs, tr
*** 4295,4301 ****
  	  {
  	    tree type = convs->u.next->type;
  
! 	    if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
  	      {
  		/* If the reference is volatile or non-const, we
  		   cannot create a temporary.  */
--- 4296,4303 ----
  	  {
  	    tree type = convs->u.next->type;
  
! 	    if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type))
! 	         && !flag_ms_extensions)
  	      {
  		/* If the reference is volatile or non-const, we
  		   cannot create a temporary.  */
Index: ./gcc/gcc/cp/call.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.517
diff -c -3 -p -r1.517 call.c
*** ./gcc/gcc/cp/call.c	28 Oct 2004 05:17:08 -0000	1.517
--- ./gcc/gcc/cp/call.c	30 Oct 2004 15:52:23 -0000
*************** reference_binding (tree rto, tree rfrom,
*** 1164,1171 ****
  
    /* [dcl.init.ref]
  
!      Otherwise, the reference shall be to a non-volatile const type.  */
!   if (!CP_TYPE_CONST_NON_VOLATILE_P (to))
      return NULL;
  
    /* [dcl.init.ref]
--- 1164,1172 ----
  
    /* [dcl.init.ref]
  
!      Otherwise, the reference shall be to a non-volatile const type, 
!      except when using fms-extensions */
!   if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !flag_ms_extensions)
      return NULL;
  
    /* [dcl.init.ref]
Index: ./gcc/gcc/cp/class.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.686
diff -c -3 -p -r1.686 class.c
*** ./gcc/gcc/cp/class.c	21 Oct 2004 21:23:38 -0000	1.686
--- ./gcc/gcc/cp/class.c	30 Oct 2004 16:02:36 -0000
*************** finish_struct_anon (tree t)
*** 2413,2419 ****
  		 we also allow unnamed types used for defining fields.  */
  	      if (DECL_ARTIFICIAL (elt) 
  		  && (!DECL_IMPLICIT_TYPEDEF_P (elt)
! 		      || TYPE_ANONYMOUS_P (TREE_TYPE (elt))))
  		continue;
  
  	      if (TREE_CODE (elt) != FIELD_DECL)
--- 2413,2420 ----
  		 we also allow unnamed types used for defining fields.  */
  	      if (DECL_ARTIFICIAL (elt) 
  		  && (!DECL_IMPLICIT_TYPEDEF_P (elt)
! 		      || TYPE_ANONYMOUS_P (TREE_TYPE (elt)))
! 		      || flag_ms_extensions)
  		continue;
  
  	      if (TREE_CODE (elt) != FIELD_DECL)
Index: ./gcc/gcc/cp/decl.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1322
diff -c -3 -p -r1.1322 decl.c
*** ./gcc/gcc/cp/decl.c	29 Oct 2004 07:16:44 -0000	1.1322
--- ./gcc/gcc/cp/decl.c	30 Oct 2004 16:00:57 -0000
*************** xref_tag (enum tag_types tag_code, tree 
*** 9235,9241 ****
  	 and record it as the "definition".
  	 When a real declaration of this type is found,
  	 the forward-reference will be altered into a real type.  */
!       if (code == ENUMERAL_TYPE)
  	{
  	  error ("use of enum %q#D without previous declaration", name);
  	  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
--- 9239,9245 ----
  	 and record it as the "definition".
  	 When a real declaration of this type is found,
  	 the forward-reference will be altered into a real type.  */
!       if (code == ENUMERAL_TYPE  && !flag_ms_extensions)
  	{
  	  error ("use of enum %q#D without previous declaration", name);
  	  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
Index: ./gcc/gcc/cp/decl.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1322
diff -c -3 -p -r1.1322 decl.c
*** ./gcc/gcc/cp/decl.c	29 Oct 2004 07:16:44 -0000	1.1322
--- ./gcc/gcc/cp/decl.c	30 Oct 2004 16:00:57 -0000
*************** decls_match (tree newdecl, tree olddecl)
*** 1098,1104 ****
  }
  
  /* If NEWDECL is `static' and an `extern' was seen previously,
!    warn about it.  OLDDECL is the previous declaration.
  
     Note that this does not apply to the C++ case of declaring
     a variable `extern const' and then later `const'.
--- 1098,1105 ----
  }
  
  /* If NEWDECL is `static' and an `extern' was seen previously,
!    warn about it except when using the fms-extensions. OLDDECL 
!    is the previous declaration.
  
     Note that this does not apply to the C++ case of declaring
     a variable `extern const' and then later `const'.
*************** warn_extern_redeclared_static (tree newd
*** 1132,1137 ****
--- 1133,1141 ----
    if (TREE_CODE (olddecl) == FUNCTION_DECL
        && DECL_ARTIFICIAL (olddecl))
      return;
+   
+   if (flag_ms_extensions)
+     return;
  
    name = DECL_ASSEMBLER_NAME (newdecl);
    pedwarn ("%qD was declared %<extern%> and later %<static%>", newdecl);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]