From 820a22fcc807f9f8a522d1ed7d07fb0433d7ef79 Mon Sep 17 00:00:00 2001
From: John Kessenich <cepheus@frii.com>
Date: Tue, 6 Oct 2015 13:11:38 -0600
Subject: [PATCH] Give error for calling a user-defined function at global
 scope.

---
 Test/110scope.vert                         |  2 +-
 Test/baseResults/110scope.vert.out         | 25 +++++++++++++++++++++-
 glslang/Include/revision.h                 |  4 ++--
 glslang/MachineIndependent/ParseHelper.cpp |  5 ++++-
 glslang/MachineIndependent/ParseHelper.h   |  2 +-
 5 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/Test/110scope.vert b/Test/110scope.vert
index 564059a2c..e28db0fdb 100644
--- a/Test/110scope.vert
+++ b/Test/110scope.vert
@@ -31,7 +31,7 @@ bool radians(bool x) // okay, can overload built-in functions
     return true;
 }
 
-
+int gi = f(1,2,3);  // ERROR, can't call user-defined function from global scope
 
 void main()
 {
diff --git a/Test/baseResults/110scope.vert.out b/Test/baseResults/110scope.vert.out
index 0a3089de3..315124614 100644
--- a/Test/baseResults/110scope.vert.out
+++ b/Test/baseResults/110scope.vert.out
@@ -1,8 +1,9 @@
 110scope.vert
 ERROR: 0:5: 'a' : redefinition 
+ERROR: 0:34: 'f' : can't call user function from global scope 
 ERROR: 0:57: 'z' : undeclared identifier 
 ERROR: 0:57: 'z' : redefinition 
-ERROR: 3 compilation errors.  No code generated.
+ERROR: 4 compilation errors.  No code generated.
 
 
 Shader version: 110
@@ -38,6 +39,16 @@ ERROR: node is still EOpNull!
 0:31      Branch: Return with expression
 0:31        Constant:
 0:31          true (const bool)
+0:34  Sequence
+0:34    move second child to first child (temp int)
+0:34      'gi' (global int)
+0:34      Function Call: f(i1;i1;i1; (global int)
+0:34        Constant:
+0:34          1 (const int)
+0:34        Constant:
+0:34          2 (const int)
+0:34        Constant:
+0:34          3 (const int)
 0:36  Function Definition: main( (global void)
 0:36    Function Parameters: 
 0:?     Sequence
@@ -115,6 +126,7 @@ ERROR: node is still EOpNull!
 0:?     'c' (global bool)
 0:?     'f' (global float)
 0:?     'tan' (global float)
+0:?     'gi' (global int)
 
 
 Linked vertex stage:
@@ -153,6 +165,16 @@ ERROR: node is still EOpNull!
 0:31      Branch: Return with expression
 0:31        Constant:
 0:31          true (const bool)
+0:34  Sequence
+0:34    move second child to first child (temp int)
+0:34      'gi' (global int)
+0:34      Function Call: f(i1;i1;i1; (global int)
+0:34        Constant:
+0:34          1 (const int)
+0:34        Constant:
+0:34          2 (const int)
+0:34        Constant:
+0:34          3 (const int)
 0:36  Function Definition: main( (global void)
 0:36    Function Parameters: 
 0:?     Sequence
@@ -230,4 +252,5 @@ ERROR: node is still EOpNull!
 0:?     'c' (global bool)
 0:?     'f' (global float)
 0:?     'tan' (global float)
+0:?     'gi' (global int)
 
diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h
index 631908033..798e1c79b 100644
--- a/glslang/Include/revision.h
+++ b/glslang/Include/revision.h
@@ -2,5 +2,5 @@
 // For the version, it uses the latest git tag followed by the number of commits.
 // For the date, it uses the current date (when then script is run).
 
-#define GLSLANG_REVISION "3.0.779"
-#define GLSLANG_DATE "05-Oct-2015"
+#define GLSLANG_REVISION "3.0.780"
+#define GLSLANG_DATE "06-Oct-2015"
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index b4f0c0b62..05d455a48 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -1124,7 +1124,10 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
                 // if builtIn == true, it's definitely a built-in function with EOpNull
                 if (! builtIn) {
                     call->setUserDefined();
-                    intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName());
+                    if (symbolTable.atGlobalLevel())
+                        error(loc, "can't call user function from global scope", fnCandidate->getName().c_str(), "");
+                    else
+                        intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName());
                 }
 
                 if (builtIn)
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index 771a43e28..3766bffd3 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -323,7 +323,7 @@ protected:
     TQualifier globalInputDefaults;
     TQualifier globalOutputDefaults;
     int* atomicUintOffsets;       // to become an array of the right size to hold an offset per binding point
-    TString currentCaller;
+    TString currentCaller;        // name of last function body entered (not valid when at global scope)
     TIdSetType inductiveLoopIds;
     bool anyIndexLimits;
     TVector<TIntermTyped*> needsIndexLimitationChecking;
-- 
GitLab