glsl/linker: link-error using the same name in unnamed block and outside
authorJuan A. Suarez Romero <jasuarez@igalia.com>
Tue, 16 Jan 2018 18:42:35 +0000 (19:42 +0100)
committerJuan A. Suarez Romero <jasuarez@igalia.com>
Tue, 16 Jan 2018 18:42:35 +0000 (19:42 +0100)
According with OpenGL GLSL 4.20 spec, section 4.3.9, page 57:

   "It is a link-time error if any particular shader interface
    contains:
      - two different blocks, each having no instance name, and each
        having a member of the same name, or
      - a variable outside a block, and a block with no instance name,
        where the variable has the same name as a member in the block."

This means that it is a link error if for example we have a vertex
shader with the following definition.

  "layout(location=0) uniform Data { float a; float b; };"

and a fragment shader with:

  "uniform float a;"

As in both cases we refer to both uniforms as "a", and thus using
glGetUniformLocation() wouldn't know which one we mean.

This fixes KHR-GL*.shaders.uniform_block.common.name_matching.

v2: add fixed tests (Tapani)

Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
src/compiler/glsl/linker.cpp

index 86ef5831b750d8776bbcde586e5338a7e78b38ca..39fc3459d3adb3129cf8a959cd7df2968d14324e 100644 (file)
@@ -1111,6 +1111,29 @@ cross_validate_globals(struct gl_shader_program *prog,
             return;
          }
 
+         /* In OpenGL GLSL 4.20 spec, section 4.3.9, page 57:
+          *
+          *   "It is a link-time error if any particular shader interface
+          *    contains:
+          *
+          *    - two different blocks, each having no instance name, and each
+          *      having a member of the same name, or
+          *
+          *    - a variable outside a block, and a block with no instance name,
+          *      where the variable has the same name as a member in the block."
+          */
+         if (var->data.mode == existing->data.mode &&
+             var->get_interface_type() != existing->get_interface_type()) {
+            linker_error(prog, "declarations for %s `%s` are in "
+                         "%s and %s\n",
+                         mode_string(var), var->name,
+                         existing->get_interface_type() ?
+                           existing->get_interface_type()->name : "outside a block",
+                         var->get_interface_type() ?
+                           var->get_interface_type()->name : "outside a block");
+
+            return;
+         }
          /* Only in GLSL ES 3.10, the precision qualifier should not match
           * between block members defined in matched block names within a
           * shader interface.