File: src/com/google/javascript/jscomp/NodeUtil.java
Issue: Closure removes needed code.
What steps will reproduce the problem?
1. Try the following code, in Simple mode
Math.blah = function(test) { test.a = 5; };
var test = new Object();
Math.blah(test); 
2. The output is
Math.blah=function(a){a.a=5};var test={};

What is the expected output? What do you see instead?
Note that Math.blah(test) was removed. It should not be. It issues a warning: JSC_USELESS_CODE: Suspicious code. This code lacks side-effects. Is there a bug? at line 4 character 9

What version of the product are you using? On what operating system?
Tested on Google hosted Closure service.

Please provide any additional information below.
Closure seems to be protective about Math in particular, and doesn't like people messing around with her? So, when I try the following code:-
var n = {};
n.blah = function(test) { test.a = 5; };
var test = new Object();
n.blah(test);

It works. When I replace n by Math, then again, Closure kicks out blah. I need that poor fellow. Please talk some sense into it.

Buggy code:
static boolean functionCallHasSideEffects(
    Node callNode, @Nullable AbstractCompiler compiler) {
  if (callNode.getType() != Token.CALL) {
    throw new IllegalStateException(
        "Expected CALL node, got " + Token.name(callNode.getType()));
  }

  if (callNode.isNoSideEffectsCall()) {
    return false;
  }

  Node nameNode = callNode.getFirstChild();

  // Built-in functions with no side effects.
  if (nameNode.getType() == Token.NAME) {
    String name = nameNode.getString();
    if (BUILTIN_FUNCTIONS_WITHOUT_SIDEEFFECTS.contains(name)) {
      return false;
    }
  } else if (nameNode.getType() == Token.GETPROP) {
    if (callNode.hasOneChild()
        && OBJECT_METHODS_WITHOUT_SIDEEFFECTS.contains(
              nameNode.getLastChild().getString())) {
      return false;
    }

    if (callNode.isOnlyModifiesThisCall()
        && evaluatesToLocalValue(nameNode.getFirstChild())) {
      return false;
    }

    // Functions in the "Math" namespace have no side effects.

    if (compiler != null && !compiler.hasRegExpGlobalReferences()) {
      if (nameNode.getFirstChild().getType() == Token.REGEXP
          && REGEXP_METHODS.contains(nameNode.getLastChild().getString())) {
        return false;
      } else if (nameNode.getFirstChild().getType() == Token.STRING
          && STRING_REGEXP_METHODS.contains(
              nameNode.getLastChild().getString())) {
        Node param = nameNode.getNext();
        if (param != null &&
            (param.getType() == Token.STRING
                || param.getType() == Token.REGEXP))
        return false;
      }
    }
  }

  return true;
}

Fixed code:
static boolean functionCallHasSideEffects(
    Node callNode, @Nullable AbstractCompiler compiler) {
  if (callNode.getType() != Token.CALL) {
    throw new IllegalStateException(
        "Expected CALL node, got " + Token.name(callNode.getType()));
  }

  if (callNode.isNoSideEffectsCall()) {
    return false;
  }

  Node nameNode = callNode.getFirstChild();

  // Built-in functions with no side effects.
  if (nameNode.getType() == Token.NAME) {
    String name = nameNode.getString();
    if (BUILTIN_FUNCTIONS_WITHOUT_SIDEEFFECTS.contains(name)) {
      return false;
    }
  } else if (nameNode.getType() == Token.GETPROP) {
    if (callNode.hasOneChild()
        && OBJECT_METHODS_WITHOUT_SIDEEFFECTS.contains(
              nameNode.getLastChild().getString())) {
      return false;
    }

    if (callNode.isOnlyModifiesThisCall()
        && evaluatesToLocalValue(nameNode.getFirstChild())) {
      return false;
    }

    // Functions in the "Math" namespace have no side effects.
    if (nameNode.getFirstChild().getType() == Token.NAME) {
      String namespaceName = nameNode.getFirstChild().getString();
      if (namespaceName.equals("Math")) {
        return false;
      }
    }

    if (compiler != null && !compiler.hasRegExpGlobalReferences()) {
      if (nameNode.getFirstChild().getType() == Token.REGEXP
          && REGEXP_METHODS.contains(nameNode.getLastChild().getString())) {
        return false;
      } else if (nameNode.getFirstChild().getType() == Token.STRING
          && STRING_REGEXP_METHODS.contains(
              nameNode.getLastChild().getString())) {
        Node param = nameNode.getNext();
        if (param != null &&
            (param.getType() == Token.STRING
                || param.getType() == Token.REGEXP))
        return false;
      }
    }
  }

  return true;
}